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. 在Visual Studio 2010/2012/2013/2015上使用C#开发Android/IOS安
  2. Android framework源码按键操作的完整流程
  3. android 之 线程间的通信
  4. android通用文件操作

随机推荐

  1. Android查看Apk签名
  2. Android音频录制、播放,这一篇就够了
  3. 属于自己的Android框架路线
  4. Android中InCallUI显示太慢问题分析
  5. API Demos 2.2 研读笔记(12)——Intents Ch
  6. Calabash 快速入门 (Android)
  7. android git 下载单个工程
  8. android 同步监听输入框,以及电话号码正则
  9. 自定义android的tab样式 《》
  10. Android(安卓)Studio 快捷键(2)