0

我正在开发一个需要根据后台线程处理结果进行UI更改的android应用程序,我首先尝试了以下代码:

        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的更改的最佳日子是什么时候。

4

4 回答 4

4

编辑:

对于长期运行的网络工作,您有几个选择。

首先检查有关此主题的 android 文档:

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

接下来,我一般将Services用于这种类型的事情:

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

我也会为您指出 vogella 教程:

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

对于从线程/异步任务/服务到 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 线程进行操作。

于 2014-01-29T15:00:13.117 回答
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);
    }
}
}
于 2014-01-29T15:03:28.340 回答
0

你需要在这里使用处理程序是文档:https ://developer.android.com/training/multiple-threads/communicate-ui.html

于 2014-01-29T15:00:54.153 回答
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

于 2014-01-29T15:12:47.907 回答