2013-09-03 1 views
0

enter image description here Начиная с Android 4.0 У меня проблема (на 2.3.6 она работает).Только исходный поток, создавший иерархию вида, может коснуться его views.onProgressUpdate

onProgressUpdate он должен быть уже в потоке пользовательского интерфейса. Я пробовал activity.runOnUiThread сейчас с версией Handler, ofc сначала был без любого из tham. Как это исправить?

public class ReadDataTask extends AsyncTask<String, String, JSONArray> { 

    private Activity activity; 
    protected ProgressDialog dlg; 

    private long startRead, endRead, endJson; 

    public ReadDataTask(Activity activity) { 
     this.activity = activity; 
     dlg = new ProgressDialog(activity); 
    } 

    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     dlg.show(); 
     startRead = System.currentTimeMillis(); 
    } 

    @Override 
    protected void onProgressUpdate(String... values) { 
     super.onProgressUpdate(values); 
     if (values != null && values.length > 0) { 
      final String msg = values[0]; 
      new Handler().post(new Runnable() { 
       public void run() { 
        dlg.setMessage(msg);// android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
       } 
      }); 
     } 
    } 


    @Override 
    protected JSONArray doInBackground(String... params) { 
      ... long task here 
      publishProgress("Converting to JSON: " + (1 + i) + "/" + dataList.size()); 
+0

Пожалуйста, разместите трассировку стека. – CommonsWare

+0

@CommonsWare обновлен скриншотом, также отмечена строка кода в источнике, где это происходит. Перемещено \t \t dlg = новый ProgressDialog (активность); topreExecute() и по-прежнему имеют ошибку –

+0

Удалите элементы «Handler» и повторите попытку с помощью 'dlg.setMessage()', вызываемого непосредственно в 'onProgressUpdate()'. Если вы получаете то же исключение, опубликуйте * полный * стек трассировки. Вы можете сделать это, выделив строки, скопировав их в буфер обмена (например, Ctrl-C) и вставив их здесь в формате источника. В несвязанной заметке удалите член данных 'activity', поскольку единственным местом, где вы можете использовать его вне конструктора, является' doInBackground() ', что является одним из мест, где вы должны * не * ссылаться на активность, к изменениям конфигурации. – CommonsWare

ответ

3

Создать обработчик только один раз в onPreExecute(), который вызывается из UI потока и сохранить ссылку на него, чем пост к нему в onProgressUpdate().

Обработчик сообщений, в которые он был создан.

0

Спасибо всем! Реализация решения:

private Activity activity; 
protected ProgressDialog dlg; 
private Handler myHandler; 

private long startRead, endRead, endJson; 

public ReadDataTask(Activity activity) { 
    this.activity = activity; 
} 

@Override 
protected void onPreExecute() { 
    super.onPreExecute(); 

    myHandler = new Handler(); 

    dlg = new ProgressDialog(activity); 
    dlg.show(); 
    startRead = System.currentTimeMillis(); 
} 

@Override 
protected void onProgressUpdate(String... values) { 
    super.onProgressUpdate(values); 
    if (values != null && values.length > 0) { 
     final String msg = values[0]; 
     myHandler.post(new Runnable() { 
      public void run() { 
       dlg.setMessage(msg); 
      } 
     }); 
    } 
} 
0

Следующие работал для меня.

myHandler.post(new Runnable() { 
      public void run() { 
       dlg.setMessage(msg); 
      } 
     }); 
Смежные вопросы

 Смежные вопросы