Android开发之AsyncTAsk的用法

来源:互联网 发布:淘宝运营培训班有用吗 编辑:程序博客网 时间:2024/04/30 19:48

大家都知道UI线程中要想实现一些耗时的操作必须开启新的线程,android为我们提供了几种异步线程的方法,大家最容易想到的就是new一个Thread开启一个线程将耗时操作放到run方法中,然后在用handler 的Message机制回传结果,然而其实android为我们还提供了一种方法就是AsyncTask,接下来我给大家仔细讲解AsyncTask的用法。
AsyncTask使UI线程的使用变得恰当和简单。这个类允许在后台执行操作并且在UI线程呈现处理的结果,无需操作线程。

一个异步任务是指在后台运行的线程,其运行结果在UI线程呈现。

一个异步任务由3个泛型和4个步骤定义完成。

三种泛型类型AsyncTask<Params, Progress, Result> 分别代表“启动任务执行的输入参数”(即传入时doInBackground(Params... params))、“后台任务执行的进度”(onProgressUpdate(Progress... values))、“后台计算结果的类型”(onPostExecute(Result result))。如果无需返回信息,可以用Void类型代替。

博主示例代码中使用的类型为AsyncTask<String, Void, List<Map<String, Object>>>

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

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组件上。

话不多说,接下来我用一个例子让大家深入理解AsyncTask,该实例是博主之前写过的一个天气查询项目大家可以借鉴借鉴。

package com.xiyou_android.AsyncTask;

iimport java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.graphics.drawable.AnimationDrawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.PopupWindow;

import android.widget.TextView;

//ICallback接口是此前写好的接口,用于接受回调数据此处不再解释

public class MainActivity extends Activity implements ICallback{
    public static final String BAIDU_URI = "http://api.map.baidu.com/telematics/v3/weather?location=";
    // 图片的连接
    public static final String BAIDU_LAST="&output=json&ak=5XwlogF5fhfTPH0Nq03A3ylG";
    private AutoCompleteTextView autoCompleteTextView;
    private Button button;
    private ListView listview;
    private View detileMessage,read;
    private ProgressDialog dialog;
    ImageView iv;
    private MyAdapter adapter;
    AnimationDrawable animation;
    private View v;
    private TextView cold,sport,qiangdu,wear,wash;
    List<Map<String, Object>> list;
    List<Map<String,Object>> list2=new ArrayList<Map<String,Object>>();
    private static final String TAG = MainActivity.class.getName();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        iniview();
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View arg0) {

                // TODO 自动生成的方法存根
    
                Log.i(TAG, autoCompleteTextView.getText().toString());
                new MyTask().execute(BAIDU_URI
                        + autoCompleteTextView.getText().toString()
                        + BAIDU_LAST);
            }
        });
    }
public void iniview(){
    autoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);
    button = (Button) findViewById(R.id.button1);
    detileMessage = this.getLayoutInflater().inflate(R.layout.detilemessage, null);
    read = this.getLayoutInflater().inflate(R.layout.read, null);
    listview = (ListView) findViewById(R.id.listView1);
    cold = (TextView)detileMessage.findViewById(R.id.cold);
    sport = (TextView)detileMessage.findViewById(R.id.sport);
    qiangdu = (TextView)detileMessage.findViewById(R.id.qiangdu);
    wash = (TextView)detileMessage.findViewById(R.id.wash);
    wear = (TextView)detileMessage.findViewById(R.id.wear);
    dialog = new ProgressDialog(this);
    dialog.setTitle("loading");
    dialog.setMessage("正在获取数据,请稍后...");
    adapter = new MyAdapter(this);
    listview.setOnItemClickListener(new dayChoice());
}
public class MyTask extends

            AsyncTask<String, Void, List<Map<String, Object>>> {

       // 此处用来显示加载框

        protected void onPreExecute() {
            super.onPreExecute();
          
            dialog.show();
        }

       //此方法用于执行主要的耗时操作返回JSON解析后的结果传给onPostExecute(List<Map<String, Object>> result)方法

        protected List<Map<String, Object>> doInBackground(String... params) {

         

            list = new ArrayList<Map<String, Object>>();
            try {
                //此处解析接口返回的JSON数据放入集合中
                HttpClient httpClient = new DefaultHttpClient();
                HttpPost httpPost = new HttpPost(params[0]);
                HttpResponse httpResponse = httpClient.execute(httpPost);
                Log.i(TAG, httpResponse.getStatusLine().getStatusCode() + "");
                if (httpResponse.getStatusLine().getStatusCode() == 200) {

                    String jsonString = EntityUtils.toString(
                            httpResponse.getEntity(), "utf-8");
                    JSONObject jsonObject1 = new JSONObject(jsonString);
                    JSONArray jsonArray = jsonObject1.getJSONArray("results");
                    JSONObject jsonObject = jsonArray.getJSONObject(0);
                    JSONArray jsonArraywaether = jsonObject
                            .getJSONArray("weather_data");
                    JSONArray jsonindex = jsonObject.getJSONArray("index");
                    for (int i = 0; i < jsonindex.length(); i++) {
                        JSONObject jsonObject_detile = jsonindex
                                .getJSONObject(i);
                        Map<String, Object> map = new HashMap<String, Object>();
                        map.put("title", jsonObject_detile.get("title"));
                        map.put("zs",jsonObject_detile.get("zs"));
                        map.put("tipt", jsonObject_detile.get("tipt"));
                        map.put("des", jsonObject_detile.get("des"));
                        list2.add(map);
                    }
                    for (int i = 0; i < jsonArraywaether.length(); i++) {
                        JSONObject jsonObject_weather = jsonArraywaether
                                .getJSONObject(i);
                        Map<String, Object> map = new HashMap<String, Object>();
                        map.put("weather", jsonObject_weather.get("weather"));
                        map.put("date", jsonObject_weather.get("date"));
                        map.put("dayPictureUrl",jsonObject_weather.get("dayPictureUrl"));
                        list.add(map);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return list;
        }
        protected void onPostExecute(List<Map<String, Object>> result) {
            super.onPostExecute(result);
            adapter.setData(result);
            // 为ListView设定适配器
            listview.setAdapter(adapter);
            adapter.notifyDataSetChanged();
            //隐藏对话框,加载完毕!
            dialog.dismiss();
     
        }
    }



    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    private class dayChoice implements OnItemClickListener {


        @SuppressWarnings("unchecked")
        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            // TODO Auto-generated method stub
             City_Message(v);
            
        }

    }

    //PopupWindow窗口中显示城市信息

    public void City_Message(View arg){

        int mScreenWidth = getWindowManager().getDefaultDisplay().getWidth();
        int mScreenHeight = getWindowManager().getDefaultDisplay().getHeight();
        final PopupWindow popup = new PopupWindow(detileMessage, mScreenWidth,
                mScreenHeight, true);
        popup.setFocusable(true);
        popup.showAtLocation(arg, Gravity.CENTER, 0, 0);
        Map<String,Object> map = new  HashMap<String, Object>();
        Map<String,Object> map1 = new  HashMap<String, Object>();
        Map<String,Object> map2 = new  HashMap<String, Object>();
        Map<String,Object> map3 = new  HashMap<String, Object>();
        Map<String,Object> map4 = new  HashMap<String, Object>();
        map = list2.get(0);
        map1 = list2.get(1);
        map2 = list2.get(2);
        map3 = list2.get(3);
        map4 = list2.get(4);
        wear.setText(map.get("des").toString());
        wash.setText(map1.get("des").toString());
        cold.setText(map2.get("des").toString());
        sport.setText(map3.get("des").toString());
        qiangdu.setText(map4.get("des").toString());
        detileMessage.findViewById(R.id.button1).setOnClickListener(new OnClickListener() {    
            @Override
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                popup.dismiss();
            }
        });
    }
    @Override
    public void onMessage() {
        // TODO Auto-generated method stub
        
    }


}

而且在使用此异步任务时还需要注意一些地方

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

2.在实例创建后需要调用execute(Params url)方法启动线程。

3.不要手动在主线程中调用onPreExecute(),doInBackground(Params... params),onProgressUpdate(Progress... values),onPostExecute(Result result)这几个方法,以上方法是系统自动按次序调用的。

4.多次调用该实例会抛出异常,或者会出现线程延迟的现象,原因在于新的线程会等待上次线程调用完毕才会调用。
在以后进行一些网络交互的操作时AsyncTask用的很广泛,大家可以在以后的编码中多多使用,谢谢大家阅读微笑
0 0
原创粉丝点击