2013-12-15 46 views
1

我有一個趕上22日在這裏。如果我使用AsyncTask來運行我的網絡活動,我無法從該線程更新我的用戶界面。安卓網線和視圖/ GUI更新

MainActivity.onCreate(...){ 
    myAsyncTask.execute(); 
    //E/AndroidRuntime(1177): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
} 

網絡活動將持續,需要在不同的線程上發生。所以,我轉過身來,super.runOnUiThread解決上述錯誤,因爲它接受Runnable作爲參數。不幸的是,的Javadoc不是清楚了,我不知道是否super.runOnUiThread打算讓一個線程或只是直接調用run。顯然,它不會讓一個線程,因爲我得到這個異常:android.os.NetworkOnMainThreadException

既然我有需要的連接的一個屏應用。做這項工作最簡單的方法是什麼?

回答

1

如果我使用的AsyncTask運行我的網絡活動,我不能從該線程

這就是爲什麼AsyncTaskonPostExecute()更新我的用戶界面。把你的UI更新邏輯放在那裏(或者onProgressUpdate(),如果你想在後臺工作進行時更新UI)。

+0

謝謝你,但我的網絡Runnable對象(裏面的AsyncTask的)發送狀態通過調用接口隨時有重新連接或連接回。我不明白它是如何做到這一點的,它甚至沒有對AsyncTask的引用。你是說我必須破解它才能通過Progress對象以某種方式獲得這些消息? – jcalfee314

+1

@ jcalfee314:'AsyncTask'用於事務性工作。如果您嘗試擁有長時間運行的線程,請分配您自己的「線程」。然後,您可以使用任意數量的手段,有後臺線程安排做主應用程序線程,工作如'runOnUiThread()'你在你的問題中引用。關鍵是你不能在主應用程序線程上執行網絡I/O。與runOnUiThread()一起使用的'Runnable'只能*安排更新UI *並不做其他事情*。你已經有一個後臺線程/線程池/無論爲後臺工作。 – CommonsWare

0

正如CommonsWare說,你可以使用onProgressUpdate()來更新UI。這裏是一個例子,我用它來製作一個又酷閃屏。

https://www.dropbox.com/s/cyz7112k4m1booh/1.png

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_splash); 
    bar=(ProgressBar) findViewById(R.id.progressBar); 
    new PrefetchData().execute(); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    // Inflate the menu; this adds items to the action bar if it is present. 
    getMenuInflater().inflate(R.menu.splash, menu); 
    return true; 
} 


private class PrefetchData extends AsyncTask<String,String,String> { 

     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      // before making http calls   

     } 

     @Override 
     protected String doInBackground(String... arg0) { 
     Random ran=new Random(); 
     int count; 
     int total=0; 
     try { 
       while(total <= 100){ 
       count=ran.nextInt(30); 
       total+=count;     
       Thread.sleep(1000); 
       if (total >= 100) publishProgress(""+100); 
     //here publishProgress() will invoke onProgressUpdate() automatically . 
       else publishProgress(""+(int) total); 
       } 
      }catch (InterruptedException e) { 
       e.printStackTrace(); 
       Log.e("Error:",e.getMessage()); 
      } 
     return null; 
     } 

     protected void onProgressUpdate(String... progress) { 
      bar.setProgress(Integer.parseInt(progress[0])); 
     } 


     @Override 
     protected void onPostExecute(String result) { 
      super.onPostExecute(result); 
      Intent i = new Intent(SplashActivity.this, MainActivity.class);    
      startActivity(i); 

      finish(); 
     } 

    }