Android: обратная кнопка во время асинтеза
У меня есть Activity, который показывает listview. На элементе щелкните по второму действию, которое запускает AsyncTask, который извлекает удаленный URL-адрес на основе того, какой элемент кликается, анализирует результаты, затем отображает эти результаты в другое представление списка. Пока выполняется задача async, у меня есть представление "загрузка", которое отображает только изображение и текст. Проблема в том, что если я инициирую действие, выполняющее задачу async, а затем вернусь назад и запустим другой экземпляр указанного действия, я получу силовое соединение.
Я пробовал
private class getlist extends AsyncTask implements OnDismissListener{
...
@Override
public void onDismiss(DialogInterface arg0) {
this.cancel(true);
}
}
Но проблема не устранена.
Я также добавил
if(!isCancelled()){
setContentView(R.layout.list);
...
etc.
}
в мой вызов onPostExecute, но либо это не препятствует переключению представления, либо проблема - это что-то еще.
logcat показывает "неожиданное возобновление, когда оно уже возобновлено.. получил RemoteException, отправив setActive (false) уведомление"
Затем немного дальше в журнале, "java.net.SocketTimeoutException: Socket не подключен"
Как я могу это решить?
обновление:
E/AndroidRuntime(19379): Uncaught handler: thread AsyncTask #2 exiting due to uncaught exception
E/AndroidRuntime(19379): java.lang.RuntimeException: An error occured while executing doInBackground()
E/AndroidRuntime(19379): at android.os.AsyncTask$3.done(AsyncTask.java:200)
E/AndroidRuntime(19379): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
E/AndroidRuntime(19379): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
E/AndroidRuntime(19379): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
E/AndroidRuntime(19379): at java.util.concurrent.FutureTask.run(FutureTask.java:137)
E/AndroidRuntime(19379): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
E/AndroidRuntime(19379): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
E/AndroidRuntime(19379): at java.lang.Thread.run(Thread.java:1096)
E/AndroidRuntime(19379): Caused by: java.lang.NullPointerException
E/AndroidRuntime(19379): at com.metatroid.android.swim.ThreadViewer.getPosts(ThreadViewer.java:153)
E/AndroidRuntime(19379): at com.metatroid.android.swim.ThreadViewer$getlist.doInBackground(ThreadViewer.java:70)
E/AndroidRuntime(19379): at com.metatroid.android.swim.ThreadViewer$getlist.doInBackground(ThreadViewer.java:1)
E/AndroidRuntime(19379): at android.os.AsyncTask$2.call(AsyncTask.java:185)
E/AndroidRuntime(19379): at java.util.concurrent.FutureTask$Sync.innerRun
Ответы
Ответ 1
Фактическим решением этой проблемы было использование ThreadSafeClientConnManager для ClientConnectionManager
например.
BasicHttpParams params = new BasicHttpParams();
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
final SSLSocketFactory sslSocketFactory = SSLSocketFactory.getSocketFactory();
schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));
ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
DefaultHttpClient httpclient = new DefaultHttpClient(cm, params);
Ответ 2
Не выполняйте действия с doInBackground()
. Доступ к действию возможен только в onPostExecute()
, publishProgress()
или onPreExecute()
, и даже тогда только с некоторой осторожностью обрабатывать изменения конфигурации и т.д.
Я бы рекомендовал сделать getlist
статическим внутренним классом, а не обычным внутренним классом. Вручную свяжите задачу и активность и разбейте эту связь при уничтожении активности или изменении ее конфигурации. Затем ваши onPostExecute()
и kin должны проверить, чтобы у него была действительная активность, прежде чем пытаться его использовать.
Это пример приложения демонстрирует часть этого - обработку изменения конфигурации. Он явно не обрабатывает сценарий кнопки BACK, но ему не нужно, поскольку он просто обновляет активность, которая находится вне экрана.
В терминах, почему getPosts()
имеет исключение NullPointerException, это зависит от вас, чтобы определить.