android 异步线程的使用

在android 中,当我们操作一个事件在5s、10s、20s(按键或触摸事件特定时间内无响应,广播、service特定时间内无法处理完成)就会报anr,为了避免这种问题,那我们就可以使用后台去处理,处理完后然后更新,异步处理一般使用AsyncTask、IntentService、Handler。

1、AsyncTask使用

asyncTask类可以将耗时的操作放到后台线程中处理操作完成后同步更新ui,asyncTask的doInBackground方法用于处理耗时的事件,在后台线程运行,执行完的结果在onProgressUpdate和onPostExecute和ui同步更新、显示,当需要同步更新的时在onProgressUpdate可通过doInBackground的publishProgress传递过去。类中的三个参数,可以根据实际需求写,第一个跟onPostExecute一样,第二个跟doInBackground的一样,第三个跟onProgressUpdate的一样。

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

        @Override
        protected String doInBackground(String... params) {

            //在后台执行,可以把运行时间比较长的代码放这里
            String result = "";//处理后返回结果
            int inputLength = params[0].length();
            int myProgress = 0;
            while (myProgress<100){
                myProgress++;
                try {

                    Thread.sleep(500);
                    publishProgress(myProgress);

                    if (myProgress<inputLength) {
                        result = result + params[0].charAt(inputLength - myProgress);
                        final String finalResult = result;
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                tvProgress.setText(finalResult);
                            }
                        });
                    }

                }catch (InterruptedException e){
                    //publishProgress(myProgress);
                }
                Log.e(TAG,"myProgress="+myProgress+ " result="+result);
            }

            return result;
        }

        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);

            //和ui线程同步更新,doInBackground执行完然后更新
            //通过ui更新、dialog或者notification报告结果
            tvProgress.setText(s);
            Log.e(TAG,"onPostExecute="+s);

        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            //和ui线程同步更新
            //更新进度条,notification或者其他ui
            sbBar.setProgress(values[0]);
            Log.e(TAG,"values[0]="+values[0]);
        }

        @Override
        protected void onCancelled(String s) {
            Log.e(TAG,"onCancelled="+s);
            super.onCancelled(s);
        }
    }
AsyncTask 的启动方式,里面的参数可传可不传,根据实际需求写。

 String input = "test ...MainActivity";
       // new MyAsyncTask().execute(input);
      //  new MyAsyncTask().onProgressUpdate(20);l
       //new MyAsyncTask().doInBackground(input);
 //       new MyAsyncTask().onPostExecute(input);
2、通过手动创建线程后台更新,下面简单代码实现

 /**
     * 在主GUI线程上调用,可同步更新
     */
    private void backgroundExecution(){

        Thread thread = new Thread(null,doBackgroundThreadProcessing,"Background");
        thread.start();


    }

    private Runnable doBackgroundThreadProcessing = new Runnable() {
        @Override
        public void run() {
            backgroundThreadProcessing();
        }
    };

    /**
     * 后台处理耗时操作
     */
    int myProgress = 0;
    private void backgroundThreadProcessing(){

        while (myProgress<10) {
            myProgress++;
            try {
                Thread.sleep(500);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        tvProgress.setText(myProgress+"");
                    }
                });
            } catch (InterruptedException e) {
                //publishProgress(myProgress);
            }
            Log.e(TAG, "myProgress1=" + myProgress);
        }
    }
使用的话之间调用backgroundExecution();便可。

3、使用IntentService实现
*IntentService是Service的子类,比普通的Service增加了额外的功能,Service不会专门启动一条单独的进程,Service与它所在应用位于同一个进程中,Service也不是专门一条新线程,因此不应该在Service中直接处理耗时的任务。
*但会创建独立的worker线程来处理所有的Intent请求,
*会创建独立的worker线程来处理onHandleIntent()方法实现的代码,无需处理多线程问题,所有请求处理完成后,IntentService会自动停止,无需调用stopSelf()方法停止Service,
*为Service的onBind()提供默认实现,返回null,
*为Service的onStartCommand提供默认实现,将请求Intent添加到队列中

简单使用,首先在权限文件中添加

<service android:name=".MyIntentService">
            <intent-filter >
                <action android:name="com.test"/>
            </intent-filter>
        </service>
然后创建MyIntentService类,在onHandleIntent中处理耗时任务

package com.example.apple.asynctask;

import android.app.IntentService;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

/**
 * Created by apple on 17/6/11.
 */

public class MyIntentService extends IntentService {

    private final String TAG = "MyIntentService";

    @Override
    public void onCreate() {
        super.onCreate();
    }


    public MyIntentService() {
        //必须实现父类的构造方法
        super("MyIntentService");
    }

    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG,"onBind=");
        return super.onBind(intent);
    }


    @Override
    public void onStart(Intent intent, int startId) {
        Log.e(TAG,"onStart=");
        super.onStart(intent, startId);
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG,"onStartCommand=");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void setIntentRedelivery(boolean enabled) {
        super.setIntentRedelivery(enabled);
        Log.e(TAG,"setIntentRedelivery=");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        //在此处理耗时任务,当处理完service会终止自己

        //Intent是从Activity发过来的,携带识别参数,根据参数不同执行不同的任务
        String action = intent.getExtras().getString("test");
//
        if (action.equals("test")){
            int myProgress = 0;
            while (myProgress<10){
                myProgress++;
                try {
                    Thread.sleep(500);
                }catch (InterruptedException e){
                }
                Log.e("ss","myProgress="+myProgress);
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}
启动使用:

 Intent intent = new Intent();
        Bundle bundle = new Bundle();
        bundle.putString("test", "test");
        intent.putExtras(bundle);
        intent.setPackage(getPackageName());  //在这里添加这行,表示兼容5.0之后
        startService(intent);



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值