发表于: 2018-11-15 23:00:00
0 775
一、今天完成的事情
ANR
ANR全名Application Not Responding, 也就是"应用无响应". 当操作在一段时间内系统无法处理时, 系统层面会弹ANR对话框提示用户是否结束当前进程。
在Android里, App的响应能力是由Activity Manager和Window Manager系统服务来监控的. 通常在如下两种情况下会弹出ANR对话框:
1)5s内无法响应用户输入事件(例如键盘输入, 触摸屏幕等).
2)BroadcastReceiver在10s内无法结束.
造成以上两种情况的首要原因就是在主线程(UI线程)里面做了太多的阻塞耗时操作, 例如文件读写, 数据库读写, 网络查询等等.
所以为了避免ANR,就不要在主线程中做一些耗时操作。
在子线程中更新UI的几种方法
1.使用Handler
private static class MyHandler extends Handler {
private final WeakReference<SetAddressFragment> mFragment;
public MyHandler(SetAddressFragment mFragment) {
this.mFragment = new WeakReference<SetAddressFragment>(mFragment);
}
@Override
public void handleMessage(Message msg) {
if (mFragment.get() == null) {
return;
}
switch (msg.what) {
case DATABASE_OK:
showProvince();
break;
default:
break;
}
}
}
创建Handler对象
private MyHandler mHandler = new MyHandler(this);
子线程发送消息通知主线程更新UI
mHandler.sendEmptyMessage(DATABASE_OK);
2.runOnUiThread()
new Thread() {
public void run() {
//这儿是耗时操作,完成之后更新UI;
runOnUiThread(new Runnable(){
@Override
public void run() {
//更新UI
imageView.setImageBitmap(bitmap);
}
});
}
}.start();
3.View.post()
imageView.post(new Runnable(){
@Override
public void run() {
imageView.setImageBitmap(bitmap);
}
});
4.AsyncTask
new DownloadImageTask().execute( "www.baidu.com" );
private class DownloadImageTask extends AsyncTask {
protected String doInBackground( String... url ) {
return loadDataFormNetwork( url[0] );//后台耗时操作
}
protected void onPostExecute( String result ) {
myText.setText( result );
}
}
二、明天计划的事情
使用JiaoZiVedioPlayer本地视频和音频。
三、遇到的问题
在子线程中对TextView执行setTxt()方法,按理说应该会报错,但实际上并没有报错,而且还执行成功了
public class ChangeUITestActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "ChangeUITestActivity";
private TextView textView;
//private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_change_uitest);
init();
}
public void init() {
Button changeInMain = (Button) findViewById(R.id.bt_change_in_main);
changeInMain.setOnClickListener(this);
Button changeInChild = (Button) findViewById(R.id.bt_change_in_child);
changeInChild.setOnClickListener(this);
textView = (TextView) findViewById(R.id.textView);
imageView = (ImageView) findViewById(R.id.imageView);
}
@Override
public void onClick(View view) {
switch(view.getId()) {
case R.id.bt_change_in_main:
if (Looper.myLooper() == Looper.getMainLooper()) {
Log.i(TAG, "run: 当前是UI线程");
}
textView.setText("在主线程中更新");
//imageView.setImageResource(R.drawable.default_head);
break;
case R.id.bt_change_in_child:
test();
break;
default:
break;
}
}
public void test () {
new Thread(new Runnable() {
@Override
public void run() {
if (Looper.myLooper() == Looper.getMainLooper()) {
Log.i(TAG, "run: 当前是UI线程");
} else {
Log.i(TAG, "run: 当前不是UI线程");
}
textView.setText("在子线程中更新");
//imageView.setImageResource(R.drawable.ico_90);
}
}).start();
}
}
四、收获
ANR
在子线程中更新UI的四种方法
评论