AsyncTask(异步任务)

一、AsyncTask

  ①AsyncTask的源码:

public abstract class AsyncTask<Params, Progress, Result>

       三种泛型类型分别代表“启动任务执行的输入参数”、“后台任务执行的进度”、“后台计算结果的类型”。

 ②相关的方法:

           一个异步任务的执行一般包括以下几个步骤:

                                 1.execute(Params... params),执行一个异步任务,需要我们在代码中调用此方法,触发异步任务的执行。

                                 2.onPreExecute(),在execute(Params... params)被调用后立即执行,一般用来在执行后台任务前对UI做一些标记。

                                 3.doInBackground(Params... params),在onPreExecute()完成后立即执行,用于执行较为费时的操作,此方法将接收输入参数和返回计算结果。在执行过程中可以调用publishProgress(Progress... values)来更新进度信息。

                                 4.onProgressUpdate(Progress... values),在调用publishProgress(Progress... values)时,此方法被执行,直接将进度信息更新到UI组件上。

                                 5.onPostExecute(Result result),当后台操作结束时,此方法将会被调用,计算结果将做为参数传递到此方法中,直接将结果显示到UI组件上。

在使用的时候,有几点需要格外注意:

                                    1.异步任务的实例必须在UI线程中创建。

                                    2.execute(Params... params)方法必须在UI线程中调用。

                                    3.不要手动调用onPreExecute(),doInBackground(Params... params),onProgressUpdate(Progress... values),onPostExecute(Result result)这几个方法。

                                    4.不能在doInBackground(Params... params)中更改UI组件的信息。

                                    5.一个任务实例只能执行一次,如果执行第二次将会抛出异常。

(注:找资料的时候,看到挺详细的挺不错。  以上面内容转自:http://blog.csdn.NET/liuhe688/article/details/6532519)

二、案例

       1、首先我们创建一个名为multithreadcho1的项目:

                实现功能:

                         点击一个按钮,每隔3秒跟新一行item数据,进度条也显示,更新玩数据后改变TextView控件的值。

       activity_main.xml布局文件:  

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/textView1"
        android:layout_marginLeft="72dp"
        android:layout_toRightOf="@+id/textView1"
        android:text="test" />
  <ListView
        android:id="@+id/listView1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button1"
        android:layout_marginTop="84dp" >
    </ListView>

    <ProgressBar
        android:id="@+id/progressBar1"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/listView1"
        android:layout_alignRight="@+id/button1"
        android:layout_below="@+id/button1"
        android:layout_marginTop="28dp" />

图片: 

           

       item.xml布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >
    
 <TextView 
        android:id="@+id/username"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="25dp"
        android:textSize="25dp"
        />

    <TextView 
        android:id="@+id/sex"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="25dp"
        android:textSize="25dp"
        />
</LinearLayout>

  图片:  

       

  这两个TextView用来显示姓名和性别。

首先创建一个Userinfos类用来封装表的,添加两个字段  Name 和Sex。

    Userinfos.java文件:

        

MainActivity.java文件:         

public class MainActivity extends Activity {
    private SimpleAdapter sa;
    private Button btn;
    private TextView tv;
    private List<Userinfos> list=new ArrayList<Userinfos>();
    private BaseAdapter adapter;
    private ListView lv;  
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //这里是UI主线程 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        for (int i = 0; i < 5; i++) {
            Userinfos u = new Userinfos();
            u.setName("小明"+i);
            u.setSex("男"+i);
            list.add(u);
        }
        lv=(ListView)this.findViewById(R.id.listView1);
        tv=(TextView)findViewById(R.id.textView1);
        btn=(Button)findViewById(R.id.button1);
        btn.setOnClickListener(new OnClickListener(){

              //模拟数据访问产生数据
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Take tk=new Take(MainActivity.this);
                tk.execute(list,adapter);//参数是传给doInBackground
            }});
        adapter=new BaseAdapter(){

            @Override
            public int getCount() {
                // TODO Auto-generated method stub
                return list.size();
            }

            @Override
            public Object getItem(int position) {
                // TODO Auto-generated method stub
                return null;
            }

            @Override
            public long getItemId(int position) {
                // TODO Auto-generated method stub
                return 0;
            }

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                // TODO Auto-generated method stub
                LayoutInflater inflater = MainActivity.this.getLayoutInflater();
                View vw;
        
                if(convertView==null)
                {
                    Log.i("View","创建对象");
                    vw = inflater.inflate(R.layout.item, null);
                    
                }
                else
                {
                    vw=convertView;
                }
                TextView tv_username = (TextView)vw.findViewById(R.id.username);
                TextView tv_sex = (TextView)vw.findViewById(R.id.sex);
                tv_username.setText(list.get(position).getName());
                tv_sex.setText(list.get(position).getSex());
                return vw;
                
            }};
    
             lv.setAdapter(adapter);
    }

创建一个Take类继承AsyncTask,进行异步任务操作。

        Take.java文件:

public class Take extends AsyncTask{
    private MainActivity activity;
    private  BaseAdapter adapter;
    private List<Userinfos> list=new ArrayList<Userinfos>();
    protected Take(MainActivity activity)
    {
        this.activity=activity;
    }
    //后台运行(数据库,蓝牙,互联网)
    @Override
    protected Object doInBackground(Object... params) {
        // TODO Auto-generated method stub
        list = (List<Userinfos>) params[0];
         Log.i("list",""+list.size());
        adapter = (BaseAdapter) params[1];

        for(int i=0;i<list.size();i++)
        {
            publishProgress(i); //这里的参数类型是 AsyncTask<Void, Integer, Void>中的Integer决定的,
            //在onProgressUpdate中可以得到这个值去更新UI主线程,这里是异步线程  。
            Log.i("time","休眠");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            list.get(i).setName("小红"+i);
            list.get(i).setSex("女"+i);
        
        }
        
        return "天气:22度";
    }
    //准备
    @Override
    protected void onPreExecute() {
        Toast.makeText(activity, "今晚有约", Toast.LENGTH_SHORT).show();
        super.onPreExecute();
    }
    //做完后执行
   @Override
  protected void onPostExecute(Object result) {
       //result的值为doInBackground方法的返回值
        String tr=result.toString();
        TextView tv = (TextView)activity.findViewById(R.id.textView1);
        tv.setText("访问完成!"+tr);
    // TODO Auto-generated method stub
    super.onPostExecute(result);
  }
   //分步完成
   //onProgressUpdate更新进度条
   @Override
protected void onProgressUpdate(Object... values) {
    // TODO Auto-generated method stub
       Log.i("dd","进入分步");
       int bar= Integer.parseInt(values[0].toString());
         bar=(bar+1)*20;
         ProgressBar progressBar = (ProgressBar)activity.findViewById(R.id.progressBar1);
         progressBar.setProgress(bar);
        adapter.notifyDataSetChanged();
        //这里是UI主线程 
    }
}

   1、通过继承AsyncTask,进行相关异步任务操作

   2、调用 publishProgress(i)方法进入onProgressUpdate进度条更新的方法,通过BaseAdapter的notifyDataSetChanged()方法通知更新数据。

   3、数据更新完后进入onPostExecute方法,该方法的result参数的值为doInBackground方法的返回值,我们固定让它返回字符串。

   4、将doInBackground方法返回的值赋给TextView。

   效果图片:

                                

              

原文地址:https://www.cnblogs.com/wdht/p/6134333.html