发表于: 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的四种方法



返回列表 返回列表
评论

    分享到