1.不能在主线程以外操作UI,android中把耗时的操作都放到子线程里面,主线程又叫UI线程

注意:

不要阻塞主线程(UI线程)
不要从主线程以外的线程更新UI(UI线程)

我们看看这个代码

public class FourActivity extends Activity {    private Button btn;    private TextView tv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_four);        tv = (TextView) findViewById(R.id.tv_four);        btn = (Button) findViewById(R.id.btn_four);        btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                new Thread(new Runnable() {                    @Override                    public void run() {                        try {                            Thread.sleep(5000);                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                        Toast.makeText(getApplicationContext(), "click button", Toast.LENGTH_SHORT).show();                    }                }).start();            }        });    }}

运行结果是:点击按钮,五秒之后,程序会错误闪退,错误日志为:

05-17 17:41:52.200 28847-28890/com.example.admin.ztest E/AndroidRuntime: FATAL EXCEPTION: Thread-2    Process: com.example.admin.ztest, PID: 28847    java.lang.RuntimeException: Can't toast on a thread that has not called Looper.prepare()        at android.widget.Toast$TN.(Toast.java:397)        at android.widget.Toast.(Toast.java:117)        at android.widget.Toast.makeText(Toast.java:280)        at android.widget.Toast.makeText(Toast.java:270)        at com.example.admin.ztest.run.FourActivity$1$1.run(FourActivity.java:37)        at java.lang.Thread.run(Thread.java:764)

2.使用runOnUiThread方法,我们修改一下程序:

package com.example.admin.ztest.run;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;import com.example.admin.ztest.R;public class FourActivity2 extends Activity {    private Button btn;    private TextView tv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_four);        tv = (TextView) findViewById(R.id.tv_four);        btn = (Button) findViewById(R.id.btn_four);        btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                new Thread(new Runnable() {                    @Override                    public void run() {                        try {                            Thread.sleep(5000);                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                        runOnUiThread(new Runnable() {                            @Override                            public void run() {                                Toast.makeText(getApplicationContext(), "FourActivity2 click button", Toast.LENGTH_SHORT).show();                            }                        });                    }                }).start();            }        });    }}

这次程序运行正常,点击按钮,五秒以后,正确提示我们的内容。

在这种情况下,可以使用Activity的runOnUiThread方法将toast的显示发布到主线程。 从主线程调用时,runOnUiThread方法立即执行传递的操作,但是当从主线程以外调用时,它会将传递的操作发布到主线程的事件队列。

3.此外,还可以使用控件.post的方式,把消息传递到主线程中

package com.example.admin.ztest.run;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;import com.example.admin.ztest.R;public class FourActivity3 extends Activity {    private Button btn;    private TextView tv;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_four);        tv = (TextView) findViewById(R.id.tv_four);        btn = (Button) findViewById(R.id.btn_four);        btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                new Thread(new Runnable() {                    @Override                    public void run() {                        try {                            Thread.sleep(5000);                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                       tv.post(new Runnable() {                           @Override                           public void run() {                               Toast.makeText(getApplicationContext(), "FourActivity3 click button", Toast.LENGTH_SHORT).show();                               tv.setText("FourActivity3 click button");                           }                       });                    }                }).start();            }        });    }}

4.还有一种,最经典的方式,扩展性最好,使用最广泛的,就是Thread+Handler实现异步消息处理

package com.example.admin.ztest.run;import android.app.Activity;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.view.View;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;import com.example.admin.ztest.R;public class FourActivity4 extends Activity {    private Button btn;    private TextView tv;    //这个地方的handler最好封装 防止内存泄漏    private Handler handler = new Handler() {        @Override        public void handleMessage(Message msg) {            if (msg.what == 100) {                String res = (String) msg.obj;                tv.setText(res);                Toast.makeText(getApplicationContext(), res, Toast.LENGTH_SHORT).show();            }        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_four);        tv = (TextView) findViewById(R.id.tv_four);        btn = (Button) findViewById(R.id.btn_four);        btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                new Thread(new Runnable() {                    @Override                    public void run() {                        try {                            Thread.sleep(5000); //模拟耗时操作,比如下载                        } catch (InterruptedException e) {                            e.printStackTrace();                        }                        Message msg = new Message();                        msg.what = 100;  //消息发送的标志                        msg.obj = "FourActivity4 click button"; //消息发送的内容如:  Object String 类 int                        handler.sendMessage(msg);                    }                }).start();            }        });    }}

 

更多相关文章

  1. Android的Message机制
  2. Android(安卓)中使用HttpUrlConnection实现get请求服务器
  3. Android(安卓)EventBus 通信
  4. android ddms查看线程
  5. Java(Android)线程池
  6. Java(Android)线程池
  7. Android开发之消息处理机制(二)——消息循环
  8. Android(安卓)Handle解析
  9. Android(安卓)中如何关闭线程

随机推荐

  1. android中的布局简要介绍
  2. android 存储数据与文件
  3. Android短信编解码方式
  4. Android(安卓)Studio witing for debugge
  5. android 与c#服务端DES加密不一致问题解
  6. Activity的布局
  7. 2013.03.19(2)———android ActivityGroup
  8. Android(安卓)- 视频提取图片方法
  9. Android程序的退出活动
  10. 【Android】获取图片和视频缩略图