zoukankan      html  css  js  c++  java
  • 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。

       效果图片:

                                    

                  

  • 相关阅读:
    把一个List拆分为几个大小一样的List
    错误统一捕捉处理新方式
    1014 C语言文法定义与C程序的推导过程
    0917 词法分析
    0909 对编译原理的理解
    mysql索引
    sql优化的基本原则
    分布式文件系统memcache和ehcache
    Java多线程与并发控制
    HTTP报文
  • 原文地址:https://www.cnblogs.com/wdht/p/6134333.html
Copyright © 2011-2022 走看看