在java中,多线程是用于提高效率性能的。而在android中,多线程是必须的!为什么?

 

首先,我们得先知道android的ANR机制。在android系统中,当系统出现死机状态,系统就会跳出一个ANR对话框,来告知用户,该情况是由应用程序造成的,而非系统本身。

 

在两种情况下会出现ANR问题:

        1) 在主线程(即UI线程)执行耗时操作,5秒之内,未响应,且期间用户又触发了下一事件。

        2) 在广播接收者的onReceiver()方法执行超过10秒中。

下图为ANR对话框:

                                  070450147.png

在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错误,如下图所示对话框:

071926302.png

 

查看日志,出现下列信息:

072407306.png

 

出现该错误是因为,只有在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);
}

 

未完待续~~~