0

我開發一個Android應用程序,需要根據後臺線程的處理結果做出UI的變化,我想下面的代碼在第一次:變化的Android UI導致​​

 Thread run_time = new Thread(){ 
      public void run(){ 
       ConnectToServer connect = new ConnectToServer(null); 
       while(true){ 
         String server_response = connect.getServerResponse(); 
         if(!server_response.equals(null)){ 
          setResponse(server_response); 
          response_received(); 
        } 
       } 
      } 
     }; 
     run_time.start(); 

但我的應用程序崩潰,因爲我試圖使UI從後臺線程變化,然後我嘗試這種方式:

 runOnUiThread(new Runnable() { 
      public void run(){ 
       ConnectToServer connect = new ConnectToServer(null); 
       while(true){ 
         String server_response = connect.getServerResponse(); 
         if(!server_response.equals(null)){ 
          setResponse(server_response); 
          response_received(); 
        } 
       } 
      } 
     }); 

,但我得到這個異常:

01-29 16:42:17.045: ERROR/AndroidRuntime(605): android.os.NetworkOnMainThreadException 
01-29 16:42:17.045: ERROR/AndroidRuntime(605):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1084) 
01-29 16:42:17.045: ERROR/AndroidRuntime(605):  at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:151) 
01-29 16:42:17.045: ERROR/AndroidRuntime(605):  at libcore.io.IoBridge.recvfrom(IoBridge.java:503) 
01-29 16:42:17.045: ERROR/AndroidRuntime(605):  at java.net.PlainSocketImpl.read(PlainSocketImpl.java:488) 
01-29 16:42:17.045: ERROR/AndroidRuntime(605):  at java.net.PlainSocketImpl.access$000(PlainSocketImpl.java:46) 

和搜索後,我發現,我必須運行代碼AsyncTask避免這些問題,但嘗試使用它時,我發現,它必須用小任務只能使用不一樣的是,在運行的線程背景全部run_time

那麼,什麼是運行一個線程或在整個RUN_TIME後臺任務,也是反映其變化的UI最好的一天。

+0

僅移動[runOnUiThread] [1]中改變UI的部分。 [1]:http://stackoverflow.com/questions/11140285/how-to-use-runonuithread – h22

+0

檢查我的答案對如何做好網絡的一些信息。 –

回答

4

編輯:

對於長時間運行的網絡工作,你有幾個選擇。

第一,formost檢查這個話題了Android文檔:

http://developer.android.com/training/basics/network-ops/index.html

接下來,我一般用服務爲這種類型的事情:

https://developer.android.com/guide/components/services.html

我會點你這個教程也是這樣:

http://www.vogella.com/tutorials/AndroidServices/article.html

對於來自線程/ asynctasks /服務的UI使用處理程序通信:

使用處理程序:

static public class MyThread extends Thread { 
    @Override 
    public void run() { 
     try { 
     // Simulate a slow network 
     try { 
      new Thread().sleep(5000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     downloadBitmap = downloadBitmap("http://www.devoxx.com/download/attachments/4751369/DV11"); 
     // Updates the user interface 
     handler.sendEmptyMessage(0); 
     } catch (IOException e) { 
     e.printStackTrace(); 
     } finally { 

     } 
    } 
    } 
    handler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
     // cal uiMethods here... 
     imageView.setImageBitmap(downloadBitmap); 
//  dialog.dismiss(); 
     } 

    }; 

從本教程摘自:

http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html

您可以將此通過定義constant_codes更具趣味,其中包含所需動作:

private int DO_THIS = 0x0; 
private int DO_THAT = 0x1; 

// in your UI: 

public void handleMessage(Message msg) { 
     // cal uiMethods here... 
     switch(msg.what()){ 
      case(DO_THIS): 
      // do stuff 
      break; 
      case(DO_THAT): 
      // do other stuff 
      break; 
     } 
     } 

// in your thread: 

Message m = handler.obtainMessage(DO_THIS); 
handler.sendMessage(m); 

如果線程代碼(異步任務,服務等)與UI分離,則可以使用廣播在兩者之間傳遞數據,然後使用此處的處理程序來處理UI線程。

0

使用此代碼 - 它可能包含編譯時錯誤,你必須做正確的

public class MainActivity extends Activity { 

@Override 
public void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 
      setContentView(R.layout.activity_main); 
    Connect connect = new Connect(); 
    connect.execute(); 
} 

class Connect extends AsyncTask<Void, String, Void> 
{ 
    @Override 
    protected Void doInBackground(Void... params) 
    { 
     ConnectToServer connect = new ConnectToServer(null); 
     while(true) 
     { 
      String server_response = connect.getServerResponse(); 
      if(!server_response.equals(null)) 
      { 
       publishProgress(server_response); 
       //setResponse(server_response); 
       response_received(); 
      } 
     } 
     return null; 
    } 

    @Override 
    protected void onProgressUpdate(String... values) { 

     super.onProgressUpdate(values); 
     setResponse(values[0]); 
    } 

    @Override 
    protected void onPostExecute(Void result) { 
     super.onPostExecute(result); 
    } 
} 
} 
+0

檢查我更新的代碼 – Rajan

+0

這是'AsyncTask',正如我所說我不能長時間使用它(所有的運行時間) – MRefaat

0

你需要「處理程序」連同「彎針」用於優化 實施例:

public void myMethod(){ 
    Thread background = new Thread(new Runnable(){ 
     @Override 
     public void run(){ 
      Looper.prepare(); 
      //Do your server process here 
      Runnable r=new Runnable() { 
        @Override 
        public void run() { 
              //update your UI from here 
        } 
      }; 
      handler.post(r); 
      Looper.loop(); 
     } 
    }); 
    background.start(); 
} 

當然,這是的,並且不使用的AsyncTask

+0

我不知道,但這段代碼並沒有讓我收到任何服務器響應,該應用程序不會崩潰,但也不會採取行動,可能是我創建處理程序的方式,我只是在'Looper.prepare()'之前使'Handler handle = new Handle()',那是OK ? – MRefaat

+1

@MRefaat:是的,很好......接收服務器響應是另一回事,你必須確保它收到了一些東西......但是在你收到之後......說一旦你收到了一些東西,真正的,所以在(/ /更新你的用戶界面)有一個條件,如果(標誌==真){那麼你可以發送你的數據到UI線程的方法或只是敬請答覆確認}否則沒有... The app dosen't cu cuz因爲我認爲服務器不能發送任何迴應 –