android多线程详解之AsyncTask

在上篇博文中我们讲到多线程之间通信的第一种办法,即通过使用handler,而在本篇博文中,我们重点来讲讲其中的第二种办法,使用AsyncTask来完成多线程通信.

AsyncTask:异步任务,从字面上来说,就是在我们的UI主线程运行的时候,异步的完成一些操作。AsyncTask允许我们的执行一个异步的任务在后台。我们可以将耗时的操作放在异步任务当中来执行,并随时将任务执行的结果返回给我们的UI线程来更新我们的UI控件。通过AsyncTask我们可以轻松的解决多线程之间的通信问题。

怎么来理解AsyncTask呢?通俗一点来说,AsyncTask就相当于Android给我们提供了一个多线程编程的一个框架,其介于Thread和Handler之间,我们如果要定义一个AsyncTask,就需要定义一个类来继承AsyncTask这个抽象类,并实现其唯一的一个 doInBackgroud 抽象方法。要掌握AsyncTask,我们就必须要一个概念,总结起来就是: 3个泛型,4个步骤。

3个泛型指的是什么呢?我们来看看AsyncTask这个抽象类的定义,当我们定义一个类来继承AsyncTask这个类的时候,我们需要为其指定3个泛型参数:

AsyncTask 

package com.wust.asy;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;



import android.app.Activity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.SimpleAdapter;
import android.widget.Toast;

public class MainActivity extends Activity {
    private final int SUCCESS = 0;//加载成功
    private final int NONEWS = 1;//该栏目下没有新闻
    private ListView lv;
    private Button btn;
    private ProgressBar pb;
    private String  path1="http://www.cnwust.com/index.html";
    private List<Map<String, Object>> list;
    private SimpleAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        lv = (ListView) findViewById(R.id.lv);
        btn = (Button) findViewById(R.id.titlebar_refresh);
        pb = (ProgressBar) findViewById(R.id.loadnews_progress);
        list = new ArrayList<Map<String,Object>>();
        adapter  = new SimpleAdapter(this,list,R.layout.list_ltem,
                new String[]{"images","titles"},
                new int[]{R.id.images,R.id.titles});
        lv.setAdapter(adapter);

        btn.setOnClickListener(new OnClickListener() {

            public void onClick(View arg0) {

                MyAsyncTask my=new MyAsyncTask();
                my.execute(path1);

            }
        });
        lv.setOnItemClickListener(new OnItemClickListener() {

            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id)
            {
                Intent intent = new Intent(MainActivity.this, NewsDetailsActivity.class);
                //把需要的信息放到Intent中
                Bundle bundle=new Bundle();
                bundle.putString("newsDate",  list.get(position).get("link").toString());
                bundle.putString("titles", list.get(position).get("titles").toString());
                intent.putExtras(bundle);

                startActivity(intent);
            }
        });

    }

    public class MyAsyncTask extends AsyncTask<String, Integer, Integer> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

            //隐藏刷新按钮
            btn.setVisibility(View.GONE);
            //显示进度条
            pb.setVisibility(View.VISIBLE); 
            //设置LoadMore Button 显示文本
            //mLoadMoreBtn.setText(R.string.loadmore_txt);


        }

        @Override
        protected Integer doInBackground(String... path1) {
            Document doc;
            try {
                doc = Jsoup.connect("http://www.cnwust.com/index.html").get();

            Elements elements=doc.select("#inner_nav  a");
            Log.i("3",elements.toString());
            for(int i=1;i<elements.size();i++ )
            {
                Map<String, Object> map=new HashMap<String, Object>();
                map.put("images", R.drawable.ic_launcher);
                map.put("titles", elements.get(i).text());
                map.put("link", elements.get(i).attr("abs:href"));
                list.add(map);
            }
            } catch (IOException e) {
                e.printStackTrace();
                return NONEWS;
            }


            return SUCCESS;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
        }

        @Override
        protected void onPostExecute(Integer values) {
            switch(values){
            case NONEWS:
                Toast.makeText(MainActivity.this, "sorry,没有新闻", Toast.LENGTH_LONG).show();
            case SUCCESS:
                Toast.makeText(MainActivity.this, "加载成功", Toast.LENGTH_LONG).show();
            }
            adapter.notifyDataSetChanged();
            //显示刷新按钮
            btn.setVisibility(View.VISIBLE);
            //隐藏进度条
            pb.setVisibility(View.GONE); 
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

}

执行的效果:

点击刷新按钮之前

点击刷新按钮之后

由于本文重点是为了着重讲讲AsyncTask的运行机制,所以对界面实现的效果比较简洁,我们通过点击刷新按钮,来实现从我们网上抓取数据的这个耗时操作,在得到数据之前,我们使用进度条来表示我们主线程当前UI状态

 protected void onPreExecute() {

        super.onPreExecute();

        //隐藏刷新按钮
        btn.setVisibility(View.GONE);
        //显示进度条
        pb.setVisibility(View.VISIBLE); 
        //设置LoadMore Button 显示文本
        //mLoadMoreBtn.setText(R.string.loadmore_txt);


    }

在获取到数据之后,然后写到list里面,再在耗时操作完后对应的这个方法里面及时更新当前的UI

   protected void onPostExecute(Integer values) {
        switch(values){
        case NONEWS:
            Toast.makeText(MainActivity.this, "sorry,没有新闻", Toast.LENGTH_LONG).show();
        case SUCCESS:
            Toast.makeText(MainActivity.this, "加载成功", Toast.LENGTH_LONG).show();
        }
        adapter.notifyDataSetChanged();
        //显示刷新按钮
        btn.setVisibility(View.VISIBLE);
        //隐藏进度条
        pb.setVisibility(View.GONE); 
    }

注意,这里只需要调用适配器adapter的notifyDataSetChanged()即可,不需要进行其他的操作.

在实际操作中,我们有时不需要一定要按照AsyncTask的三个参数定义的意义来重新套用,可以灵活的变通使用,只要代码能到达我们想要的效果就行,在上段实例代码中,我们定义的三个参数就与它们的本义没有多大联系

最后要注意的是在使用AsyncTask做异步任务的时候必须要遵循的原则:

1.AsyncTask类必须在UI Thread当中加载,在Android Jelly_Bean版本后这些都是自动完成的
2.AsyncTask的对象必须在UI Thread当中实例化
3.execute方法必须在UI Thread当中调用
4.不要手动的去调用AsyncTask的onPreExecute, doInBackground, publishProgress, onProgressUpdate, onPostExecute方法,这些都是由Android系统自动调用的
5.AsyncTask任务只能被执行一次

关于对AsyncTask的讲解就到此为止了,本片博文的部分内容也有参考这片文章,有兴趣爱好的同学可以看看原文:
http://www.cnblogs.com/xiaoluo501395377/p/3430542.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值