暴走吧小草莓

导航

为什么使用多线程编程


当我们需要执行一些耗时操作时,比如发起网络请求或者读取数据库时,如果不把这类操作放在子线程,便可能会阻碍UI
线程(即主线程)其他逻辑的运行,从而导致界面卡顿或者主线程被堵塞,如果卡顿时间超过5秒,就会导致系统ANR报错。
因此,在执行耗时操作时,我们要另起线程执行。

需要注意的是Android中的UI是线程不安全的,也就是说,要想更新应用程序中的UI元素,必须要在主线程中进行,否则可能出现异常。
举例:新建一个AndroidThreadTest项目,然后修改activity_main.xml中的代码,如下所示:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="match_parent">

<Button
   android:id="@+id/change_text"
   android:layout_width="match_parent"
   android:layout_height="wrap_content"
   android:text="Change Text" />

<TextView
  android:id="@+id/text"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_centerInParent="true"
  android:text="Hello world"
  android:textSize="20sp" />

</RelativeLayout>

我们希望通过点击button,可以将textView中的字符串改成Nice to meet you
接下来修改MainActivity中的代码,如下所示:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {

   private TextView text;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.activity_main);
     text = (TextView) findViewById(R.id.text);
     Button changeText = (Button) findViewById(R.id.change_text);
     changeText.setOnClickListener(this);
}

   @Override
   public void onClick(View v) {
     switch (v.getId()) {
         case R.id.change_text:
         new Thread(new Runnable() {
        @Override
        public void run() {
           text.setText("Nice to meet you");
    }
  }).start();
     break;
     default:
     break;
  }
}

可以看到,我们在Change Text按钮的点击事件里面开启了一个子线程,然后在子线程中调用TextView的setText()
方法将显示的字符串改成Nice to meet you。代码的逻辑非常简单,只不过我们是在子线程中更新UI的。现在运行一下
程序,并点击Change Text按钮,你会发现程序果然崩溃了。由此说明Android中确实不允许子线程中更新UI。

但有时,我们需要根据子线程的运行结果来更新UI,该怎么做呢? Android为我们提供了专门针对此问题的解决机制-异步消息处理机制(见下文)。

posted on 2018-01-20 14:17  暴走吧小草莓  阅读(102)  评论(0编辑  收藏  举报