android中的多线程基础问题
在java中,多线程是用于提高效率性能的。而在android中,多线程是必须的!为什么?
首先,我们得先知道android的ANR机制。在android系统中,当系统出现死机状态,系统就会跳出一个ANR对话框,来告知用户,该情况是由应用程序造成的,而非系统本身。
在两种情况下会出现ANR问题:
1) 在主线程(即UI线程)执行耗时操作,5秒之内,未响应,且期间用户又触发了下一事件。
2) 在广播接收者的onReceiver()方法执行超过10秒中。
下图为ANR对话框:
在android中,主线程执行布局,事件监听等操作,不允许有耗时操作,而耗时操作又是程序中不可避免的,所以,多线程是必须的。当我们要执行耗时操作时,我们就应该起一个子线程来进行耗时操作。下面代码模拟子线程耗时操作:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView1 = (TextView) findViewById(R.id.textView1); mTextView2 = (TextView) findViewById(R.id.textView2); Button button1 = (Button) findViewById(R.id.button1); OnClickListener listener = new OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.button1: new Thread() { public void run() { // 模拟耗时操作 try { Thread.sleep(6000); mTextView1.setText("linli"); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); Log.e("MainActivity", "button1"); break; case R.id.button2: break; default: break; } } }; button1.setOnClickListener(listener); }
执行以上代码会出现FC错误,如下图所示对话框:
查看日志,出现下列信息:
出现该错误是因为,只有在UI线程中,才可以更新UI控件的属性。
想解决这类的FC错误,就得引用android的新技术——线程间通讯。
android中,为线程间通讯提供了两种方法:
1) Handler;
2) AsyncTask;
1. 首先是Handler的用法:
1) 创建一个继承Handler类的类,重写handleMessage()方法,如MyHandler类;
2) 在子线程中,将更新UI控件的语句信息用所创建的类(MyHandler)的类型变量(myHandler)推送至所创建的类(myHandler.sendMessage(msg));
3) 在handleMessage()方法中执行UI控件的更新操作;
代码如下:
private Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { String result = (String) msg.obj; switch (msg.what) { case 1: mTextView1.setText(result); break; case 2: mTextView2.setText(result); break; default: break; } } }; private TextView mTextView1; private TextView mTextView2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTextView1 = (TextView) findViewById(R.id.textView1); mTextView2 = (TextView) findViewById(R.id.textView2); Button button1 = (Button) findViewById(R.id.button1); OnClickListener listener = new OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.button1: new Thread() { public void run() { // 模拟耗时操作 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } String result = "从网络获取的结果"; Message msg = new Message(); msg.what = 1; msg.obj = result; // 发送到main线程 mHandler.sendMessage(msg); // textView.setText(result); } }.start(); Log.e("MainActivity", "button1"); break; case R.id.button2: Log.e("MainActivity", "button2"); break; } } }; button1.setOnClickListener(listener); Button button2 = (Button) findViewById(R.id.button2); button2.setOnClickListener(listener); }
未完待续~~~
转载于:https://blog.51cto.com/shiouwen/1275951