AsyncTask专题之一 为啥要使用AsyncTask

来源:互联网 发布:双色球数据分析频率图 编辑:程序博客网 时间:2024/05/22 05:08

验证一、尝试在UI线程中做耗时操作。
在UI线程中输出100个数,存放到TextView中,每sleep 会儿就存一个
演示代码如下:

package com.yztc.day0710_wang_02;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.widget.TextView;public class MainActivity extends AppCompatActivity {    private TextView mTextView;    public static final String TAG = "MainActivity";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mTextView = (TextView) findViewById(R.id.tv_show);        //Thread方法中,可以使用currentThread()获得线程对象        //使用getId()获得线程id,使用getName()获得线程名字        Log.d(TAG,"当前线程的id" + Thread.currentThread().getId() + ",当前线程的名字:" + Thread.currentThread().getName());        for(int i = 0;i < 100;i ++){            try {                Thread.sleep(5000);            } catch (InterruptedException e) {                e.printStackTrace();            }            //setText中的参数要求是charsequences ,i 是一个int,加上一个""就转为字符序列            mTextView.setText(i + "");        }    }}

一会儿就报错了,
ANR异常
ANR(application not response)应用程序无响应

 E/ActivityManager: ANR in com.yztc.day0710_wang_02 (com.yztc.day0710_wang_02/.MainActivity)                                                Reason: keyDispatchingTimedOut                                                Load: 0.54 / 0.4 / 0.16                                                CPU usage from 28445ms to 0ms ago:

结论:在UI线程中不能进行耗时操作

验证二、尝试在子线程中进行耗时操作,并更新UI
在xml文件中添加一个按钮,当点击按钮的时候,启动子线程,循环100个数字,每5秒更新一次
TextView
代码如下所示:
XML布局:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.yztc.day0710_wang_02.MainActivity">    <TextView        android:id="@+id/tv_show"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Hello World!"/>    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@id/tv_show"        android:text="启动子线程"        android:onClick="onStartSubThread"/></RelativeLayout>

验证代码:把验证一的代码注释掉了
关于线程启动的方式,这里如果小伙伴忘了可以看下:
1.继承Thread类
class A extends Thread{
//重写run()方法
}
A a = new A();
a.start();
2.实现runnable接口
class B extends implement Runnable{
//重写run()方法
}
B b = new B();
new Thread(b).start();

package com.yztc.day0710_wang_02;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.TextView;public class MainActivity extends AppCompatActivity {    private TextView mTextView;    public static final String TAG = "MainActivity";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mTextView = (TextView) findViewById(R.id.tv_show);        //Thread方法中,可以使用currentThread()获得线程对象        //使用getId()获得线程id,使用getName()获得线程名字        Log.d(TAG, "当前线程的id" + Thread.currentThread().getId() + ",当前线程的名字:" + Thread.currentThread().getName());//        for (int i = 0; i < 100; i++) {//            try {//                Thread.sleep(5000);//            } catch (InterruptedException e) {//                e.printStackTrace();//            }//            //setText中的参数要求是charsequences ,i 是一个int,加上一个""就转为字符序列//            mTextView.setText(i + "");//        }    }    //响应按钮事件    public void onStartSubThread(View view) {        new Thread(){            @Override            public void run() {                super.run();                Log.d(TAG,"子线程的id=" + Thread.currentThread().getId() + ",子线程的名称=" + Thread.currentThread().getName());                for (int i = 0;i < 100;i ++){                    try {                        Thread.sleep(5000);                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                    mTextView.setText("" + i);                }            }        }.start();    }}

报错,异常信息如下所示:

 E/AndroidRuntime: FATAL EXCEPTION: Thread-86                                                 android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

结论:只能在UI线程中去更新UI

那么既然UI线程中不能去做耗时操作,而子线程中可以做耗时操作,但子线程中又不能更新UI怎么办呢?

答曰:可以使用AsyncTask (不会念不要紧,I think task哈哈~~)

0 0