Приложение зависает, потому что ваш метод copy()
занимает много времени. Следует также помнить, что вы выполняете эту трудоемкую операцию в главном потоке , который также отвечает за поддержание пользовательский интерфейс.
Поскольку поток пользовательского интерфейса занят завершением длительной операции, он избегает обновления и выполнения операций пользовательского интерфейса. В результате приложение, наконец, зависает и зависает.
Теперь есть два способа справиться с этой ситуацией:
Вы можете заставить пользователя приложения ждать, пока ваш метод copy()
не будет завершен, показывая вращающийся загрузчик незадолго до запуска метода copy()
и скрытия загрузчика после его завершения. Этот метод загрузчика гарантирует, что пользователь не выполнит никакого события, связанного с пользовательским интерфейсом (например, нажатие кнопки), пока метод copy()
не будет завершен. код для отображения загрузчика, извините, код находится в Kotlin .
class DialogUtil private constructor() {
init {
throw AssertionError()
}
companion object {
private var progressDialog: ProgressDialog? = null
fun showAlertDialog(context: Context, message: String?) {
AlertDialog.Builder(context).setMessage(message)
.setCancelable(false).setPositiveButton("OK") {
dialogInterface, _ -> dialogInterface.dismiss() }.show()
}
fun showProgressDialog(context: Context) {
progressDialog = ProgressDialog(context)
progressDialog!!.setProgressStyle(ProgressDialog.STYLE_SPINNER)
progressDialog!!.requestWindowFeature(Window.FEATURE_NO_TITLE)
progressDialog!!.setMessage("Please wait...")
progressDialog!!.setCancelable(false)
progressDialog!!.isIndeterminate = true
progressDialog!!.show()
}
fun hideProgressDialog() {
if (progressDialog != null) {
progressDialog!!.dismiss()
}
}
}
}
Создайте вспомогательный класс, как указано выше для loader, а затем чуть выше строки, где начинается ваш метод copy()
, вызовите этот загрузчик следующим образом
DialogUtil.showProgressDialog(this)
Above ] этот относится к контексту, поэтому, если метод copy()
находится во фрагменте, вам нужно передать activity
(getActivity () в java) вместо него.
Как только ваш метод copy()
завершится, вы можете скрыть спиннинг-загрузчик следующим образом:
DialogUtil.hideProgressDialog()
напишите эту строку чуть ниже вашего метода copy()
.
Второй способ - запустить метод copy()
в каком-то другом потоке, чтобы вашему потоку пользовательского интерфейса (основному потоку) не нужно было заботиться о методе copy()
и ваше приложение было спасено от зависания. . Одно из преимуществ этого метода заключается в том, что, хотя ваш метод copy()
все еще находится в процессе выполнения, пользователь все еще может выполнять связанные с пользовательским интерфейсом события без какого-либо дрожания или задержки. Я предлагаю вам использовать AsyncTask для выполнения вашего Метод copy()
, поскольку он может выполнять длинные задачи в рабочем потоке, а затем может предоставить вам возможность уведомить пользователя о завершении задачи в основном потоке (UI). Код выглядит следующим образом:
private class MyTask extends AsyncTask<X, Y, Z>
{
protected void onPreExecute(){
//any specific setup before you start copy() method , runs on UI
// thread
}
protected Z doInBackground(X...x){
// your copy() method itself, runs on worker thread other than main UI
// thread, don't perform any UI related activities from here , since
// it is the worker thread
}
protected void onProgressUpdate(Y y){
//any event you wanna perform , while the task is in progress, runs on
//UI main thread
}
protected void onPostExecute(Z z){
//the event you wanna perform once your copy() method is complete, runs
//on UI main thread
}
}
После определения класса вы можете запустить этот AsyncTask следующим образом:
MyTask myTask = new MyTask();
myTask.execute(x);
Куда бы я ни упомянул пользовательский интерфейс, Это означает, что оттуда вы можете выполнить любую задачу или операцию, связанную с пользовательским интерфейсом. Следует помнить, что события пользовательского интерфейса могут выполняться только из потока пользовательского интерфейса, если вы попытаетесь выполнить операции, связанные с пользовательским интерфейсом, из потока, отличного от потока пользовательского интерфейса (основного потока) , приложение может неожиданно закрыться.
Я предлагаю сделать этот AsyncTask как внутренний класс, в самом фрагменте, вместо создания нового класса полностью.
Одно преимущество я вижу в использовании "запаса" Python, это включено с Mac OS X, состоит в том, что это делает развертывание на других Mac куском пирога. Я не знаю, каков Ваш сценарий развертывания, но для меня это важно. Мой код должен работать на любом количестве Mac на работе, и я пытаюсь минимизировать объем работы, который это берет для выполнения моего кода всех тех систем.
Вот некоторая полезная информация для запущения Вас. http://www.python.org/download/mac/
Я настоятельно рекомендовал бы использованию MacPorts с Porticus для управления Вашей установкой Python. Это требует времени для создания всего, но преимущество состоит в том, что независимо от того, что Вы создаете себя, будет создан против тех же библиотек, таким образом, Вы не будете иметь к futz вокруг со статически связанными общими объектами, и т.д. если Вы захотите, чтобы Ваш материал Python работал с Apache, PostgreSQL, и т.д.
Если Вы принимаете решение пойти этим путем, не забудьте устанавливать python_select
порт и использование это, чтобы заставить Вашу систему использовать Python, установленный от MacPorts.
Как добавленная премия, у MacPorts есть пакеты для большинства основных яиц Python, поэтому если необходимо смочь сделать, чтобы MacPorts держал Вас в курсе последних версий всего этого :)
Как насчет EPD от Enthought? Да, это является большим, но это - сборка платформы и включает вещи как wxPython, vtk, numpy, scipy, и ipython встроенный.
Зависит, для чего Вы используете Python. При использовании MacOS funitionality и вещей как PyObjC, Вы являетесь, вероятно, лучшими из с MacPython или Python, предоставленным Apple.
Я использую Python на своем Mac главным образом для разработки серверных приложений, которые позже будут работать на полях FreeBSD & Linux. Для этого я использовал Python штрейкбрехера в течение нескольких лет и начиная с Python MacPorts. С Mac портирует его, просто добавить требуемые c модули (как драйвер базы данных и т.д.). Также легко сохранить две Версии Python (2.5 и 2.6 в моем случае) вокруг.
Я использовал, "компилируют Ваш собственный" Python для тестирования пред3.0 Python, но обычно я нахожу руководящие зависимости к c модулям болезненными, если сделано вручную.
Благодаря easy_install, устанавливающему чистый Python модули, быстро и легок для всех упомянутых выше опций.
Я никогда не был в значительной степени человеком IDE. Для разработки я использую подверсию командной строки, установленную MacPorts, Textmate, и иногда Expandrive действительно непосредственно получают доступ к файлам на серверах. Я лично очень завишу от Bicyclerepairman для Textmade для обработки моих потребностей рефакторинга.
Другие, кажется, очень довольны Eclipse & Pydev.
Я рекомендую Python (какой-либо Python?) плюс оболочка ipython. Мой новый опыт с MacPython был MacPython 2.5, и я нашел, что НЕАКТИВНЫЙ срыв использовал в качестве редактора. Это не очень featureful, и its', очень медленные для прокрутки больших количеств вывода.
В моей среде окон я использую Eclipse и PyDev, который работает вполне хорошо вместе, даже если это немного редко. По-видимому, та же самая среда доступна для Mac также, таким образом, я предлагаю загрузить Eclipse и использовать внутреннюю функцию программного обеспечения обновления для обновления PyDev с URL http://pydev.sourceforge.net/updates/. Для дальнейшего изучения PyDev посмотрите здесь.
Я рекомендую использовать Виртуальные среды Python, особенно если Вы используете Timecapsule, потому что Timecapsule создаст резервную копию всего, кроме модулей, которые Вы добавили к Python!
Предоставленный Python Apple довольно стар – моя установка тигра имеет 2.3.5. Это не может быть проблемой для Вас, но Вы пропустили бы много. Кроме того, существует риск, что Apple обновит его. Я не уверен, если перемещение от 2.3.5, чтобы (сказать) 2.4 заставило бы код повреждаться, но я предполагаю, что это возможно. Это недавно произошло с людьми жемчуга: http://developers.slashdot.org/article.pl?sid=09/02/18/1435227
Macpython является сборкой платформы (как Apple, я верю). Честно говоря, я не уверен точно, что это означает, но это - предпосылка для некоторых модулей, в особенности wxPython. Если Вы получите Python от macports или штрейкбрехера, то Вы не сможете выполнить wxPython (если Вы не выполните его через X11).
На основе количества ошибок и пропуска люди встречались в Python Leopard (просто здесь на ТАК!), я не мог рекомендовать ту версию. например, см.:
Я выбрал бы MacPorts.
Это не устраняет Ваш существующий Python, предоставленный Apple, так как это устанавливает по умолчанию в /opt/local/bin
(играет по правилам с ним), и плюс он легко загрузить и установить дополнительные модули Python (даже двоичные модули, которые необходимо скомпилировать!). Я использую GUI Porticus для поддержания установленного списка моего MacPorts пакетов, включая Python.