Запускаем консольные Java приложения на Android



    Речь пойдёт о проекте-утилитке, который может пригодиться всякому кто изучает Java и не всегда имеет под рукой ПК для просмотра работы примера кода в полевых условиях (как-то — в метро, маршрутке, кафешке и т.д.).

    Необходимость создать сие поделище возникла когда я готовился к OCJP-сертификации. После успешного прохождения оной, решил предоставить плоды своих задумок на обозрение уважаемым участникам хабрасообщества.

    Ноутбука у меня нет, а запускать примеры кода на смартфоне, сидя на кухне за чашечкой чая, удобно.

    Так уж повелось, что бо́льшая часть примеров для обучения обычно приводится именно в формате консольных программ. Замечательный инструмент AIDE позволяет собирать Android-приложение на основе Eclipse-проектов. Возможность, увы, недостаточная для запуска консольных примеров методом копипасты.

    Дело за малым — перенаправляем потоки ввода/вывода в UI контролы:

        private static OutputStream mOutputStream = new OutputStream() {
                @Override
                public void write(int b) {
                    MainActivity.getInstance().write((byte)b);
                }
        };
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            ...
            System.setOut(new PrintStream(mOutputStream));
            System.setErr(new PrintStream(mOutputStream));
            ...
        }
    


    Консольная программа стартует в отдельном потоке из обработчика activity onResume():

    			@Override
    			public void run() {
    		    	try {
    			    	//
    			    	// Здесь запускается консольное приложение
    			    	//
    		    		Program.main(new String[0]);
    		    	} catch (Throwable ex) { // Тут же ловим все исключения
    		    		setErrorColor();
    		    		ex.printStackTrace();
    		    	}
    			}
    


    Здесь же можно задавать аргументы командной строки — старый добрый args. Пример — запуск BankTellerSimulation на 10 секунд:

    BankTellerSimulation.main(new String[] { "10" });
    


    Поддерживается работа нескольких потоков (SimpleThreadsTest):



    HorseRace и BankTellerSimulation — примеры более сложных многопоточных приложений (взяты из книги Thinking in Java, 4th Ed by Bruce Eckel).

    Ошибки времени выполнения

    Пример ErrorTest:

    class FuuuuuuException extends RuntimeException {
    	public FuuuuuuException(String message) {
    		super(message);
    	}
    }
    ...
    throw new FuuuuuuException("!!!TROLLFACE!!!");
    


    Получаем исключение:



    Ввод

    Напоследок, для полноты возможностей, был добавлен консольный ввод. Пока что мои познания в области пользовательского интерфейса Android не велики. Кое-как впихнуть EditText удалось, но результат не идеален :)

    Приглашение ввода строки (ReadingInputTest):



    Далее:



    Функции меню

    Exit выключает процесс через System.exit(0).

    Программа «одноразовая». Повторных перезапусков нет (не хотелось возиться с очисткой значений статических полей).

    Что делает Clear — большой секрет.

    Что не работает

    assert'ы Java. Т.е. оператор

    assert "Cat".equals("Dog");
    

    исключение java.lang.AssertionError не кинет. Не путать с assert'ами JUnit — с ними всё в порядке!)
    • Класс Console.
    • Поле ввода не всегда подхватывает фокус.

    Файлы проекта

    Исходники можно забрать с GitHub, либо скачать zip-архив с проектами для Android Studio и Eclipse.

    Описанные примеры находятся в пакете com.examples. Все примеры можно без изменений запускать на обычном ПК (run everywhere!).
    AdBlock has stolen the banner, but banners are not teeth — they will be back

    More
    Ads

    Comments 22

      +3
      Пожалуй лучше если TrollfaceException будет кидать сообщение Fuuuuuuuu :)

      А пот делу — классная идея. В закладки.
        0
        Спасибо :)
          +2
          Нет, лучше если бы нормально назвали исключение, потому что во-первых это плохой пример, во-вторых есть люди, которым надоели эти тупые комиксы или вообще не нравились.
            0
            Да я тоже не особо фанатею от этих рисунков, но просто люблю последовательность. :)
              –2
              Нелепое название исключения и несуразный текст резко выделяются и тем самым лучше обращают на себя внимание в кучке системных и правильных наименований стека вызовов. Таким образом я намеревался создать контраст чтоб читатели сразу увидели то на нужно обратить внимание.
            +1
            Советую еще всем заинтересовавшимся посмотреть на программку Terminal IDE. В составе есть инструкции и примеры по написанию, компиляции и запуску приложений. Рут не требуется.
              0
              Да. Она крутая, особенно порадовали честные bash, и mc. Только там java компилятор старый, какаято старая уже не развивающаяся ветка(сейчас уже не помню).
              И еще я пытался к ней компилятор scala прикрутить, но не осилил. В старой версии дальвика были проблемы с количеством ссылок на методы и dexing такого большого проекта не проходил.
              0
              Как раз то, что мне нужно. А скроллинг вывода есть?
                –1
                Есть. Всё что выводится остаётся в TextView. Даже когда меняется ориентация экрана.
                0
                Эта ваша штука умеет загружать откомпилированные Java-классы? A то я на SL4A в этом месте неприятно наколося…
                  –1
                  Не умеет. Цель была другая — скомпилировать код на смартфоне используя AIDE и выполнить его как консольное приложение. Но не запускать готовые .class файлы.
                    0
                    Не знаю как сейчас ( не писал под андроид после froyo ), но в спеке по Dalvik VM за 2010 год, на 3-й странице в последнем абзаце (The Dex File Format) указано что
                    Java source code is still compiled into .class files. But after .class files
                    are generated, the “dx” tool is used to convert the .class files into a .dex, or Dalvik Executable, file.
                    Whereas a .class file contains only one class, a .dex file contains multiple classes. It is the .dex file
                    that is executed on the Dalvik VM.
                    то есть технически писать на джава возможно, если переписать каким-то образом dx-tool, правда не знаю как дела обстоят с многопоточностью.
                      0
                      Где-то мелькала идея класслоадера, который бы дексил на лету.
                        0
                        идея не нова, например тут описывается как написать свой декстул на джава
                    +1
                    Что не работает

                    • assert'ы.
                    • Класс Console.

                    с классом Console разобрались, sandboxing строгий не позволяет, а что же мешает использовать JUnit Assert?

                    import static junit.framework.Assert.*;

                    методы assertTrue, assertEquals, assertNull по-прежнему доступны, с оговоркой что нужно подчистить в .classpath все упоминания org.junit
                      +1
                      Ничто не мешает использовать Assert JUnit'a. Поэтому его нет в списке «Что не работает» :)
                        –1
                        ну а что ж вы тогда пугаете народ, это не работает, то не работает. все работает!
                          +1
                          Тут надо уточнить какие именно assert'ы. У меня имелась в виду конструкция языка — ключевое слово assert.

                          То есть следующий код исключение java.lang.AssertionError на строке (3) не кинет. Однако же вызов (4) сгенерирует junit.framework.AssertionFailedError:

                          public static void main(String[] args) {
                          	assert false; // (3)
                          	junit.framework.Assert.assertTrue(false); // (4)
                          }
                          

                          ok. Поправил в тексте. Спасибо.
                            0
                            без вопросов! я просто за справедливость! :)
                      –1
                      Вопрос, а чем был обоснован для андройда выбор языка java? Не могу найти ответ.

                    Only users with full accounts can post comments. Log in, please.