AsyncTask和thread以及Service和IntentService的关系和区别

首先回答你第一个,什麽是线程,还有AsyncTask,估计是你大概的线程通讯.

1、同步:

在一个线程执行,先执行完了前面的代码,才会执行后面的代码,是阻塞的。

2、异步:

开启一个新的线程执行,不会等前面的代码执行完,就会执行后面的代码,是非阻塞的。

3、什麽是main(UI)线程:

android启动的第一个线程。主要负责处理ui和事件的工作。

【特别注意】

1、更新ui只能在ui线程进行,不可以在其他线程更新ui,否则会崩溃。

2、在ui线程不可以做耗时操作,比如网络请求等,如果做耗时操作,就会阻塞ui线程,就会导致界面卡顿。会出现ANR(application not response、应用无响应)。

4、异步通讯:

那么我们要请求网络或者其他耗时操作的时候怎么办?这就涉及到异步通讯或者叫线程通讯。

先在子线程加载数据,做耗时操作,然后把取得的数据传递给ui线程,让ui线程来更新ui。

5、线程通讯的方式:

1、Handler(可以理解成消息获取的工具,非官方翻译)

使用方法:

1、在主线程实例化一个Hanlder,复写handleMessage()方法,在里面做更新ui的操作;

2、让子线程持有handler的引用,使用handler来发送消息。

传递参数:

获取消息,请使用handler.obtainMessage();

what:用来区分消息的类型

obj:传递复杂参数

arg1:传递简单的int参数

arg2:传递简单的int参数

Handler的原理:

1、在主线线程新建一个handler,在子线程中调用这个Handler发送消息到消息队列,在发送的时候,message.target会保存发送它的Handler;

2、主线程只带一个looper循环,会不断的从消息队列中取出消息,如果没有消息,就阻塞;

3、在主线程中调用message.target(发送他的Handler)的DispatchMessage,间接调用handlerMeaage来处理消息。

在子线程中使用Handler:

因为使用Handler需要消息循环,子线程中没有消息循环,所以,这里有2中方法:

1、使用主线程的loop(getMainLooper()),然后在创建Handler的时候,把这个获取的主线程的loop传进去;但是,这种方法,子线程中的Handler还是在主线程处理消息。因为用的主线程的循环。

2、给子线程建立消息循环:

先调用 Looper.prepare();建立消息循环,消息队列等。

在建立了Handler之后,调用Looper.loop(),开始loop循环,如果不掉用,循环就不会开始运行,就不会处理消息。

代码如下:

new Thread(new Runnable() {

@Override

public void run() {

Log.i(TAG, "run: ");

//建立消息循环,建立消息队列

Looper.prepare();

han=new Handler(){

@Override

public void handleMessage(Message msg) {

Log.i(TAG, "handleMessage: "+Thread.currentThread().getName());

}

};

//开始loop循环

Looper.loop();

}

}).start();

Handler的其他使用

1、hander.post()方法可以直接把一个代码post到主线程执行;

handler.post(new Runnable() {

@Override

public void run() {

//这里在主线程执行

}

});

2、activity的runOnUITHread();

runOnUiThread(new Runnable() {

@Override

public void run() {

//这里在主线程执行

}

});

3、任何控件的Post方法();

tv.post(new Runnable() {

@Override

public void run() {

//这里在主线程执行

}

});

4、延时执行:

handler.postDelayed(new Runnable() {

@Override

public void run() {

//需要延时执行的代码

}

},1000);

getMainLooper();获得主线程looper, myLooper()得到的是当前线程 内部调用 ThreadLocal.get();

2、HandlerThread:支持Handler的线程,内部实现了Loop循环

使用方法:

//新建一个代loop的子线程

final HandlerThread handlerThread=new HandlerThread("zixiancheng");

//让子线程开始执行

handlerThread.start();

//把线程的looper传给Hander运行,这样,这个Hander就在zixianchegn中执行了。

handler=new Handler(handlerThread.getLooper())

【5星级 注意!!】

使用了这个HandlerThread,他会开启一个循环一直跑,所以,在退出程序的时候,一定要调用quit(),退出循环。

@Override

protected void onDestroy() {

handlerThread.quit();

super.onDestroy();

}

 

3、AsyncTask:异步任务

继承自AsyncTask,写一个自己的异步任务,注意,AsyncTask有3个泛型。

从做到又分别是:参数的类型,进度的类型,返回结果的类型。

execute():执行这个异步任务,必须在主线程中调用

onPreExecute():在执行异步任务之前调用

doInBackground():执行任务的函数,比如去请求网络

publishProgress():在请求的过程中,更新一下进度,会调用onProgressUpdate

onProgressUpdate():更新进度,在主线程中运行

onPostExecute():请求完了以后,可以保存结果

cancel():取消任务的时候调用。

以上,是关于线程通讯,在回答你关于service:

 

service使用方法

1、startService:

特点:

仅仅需要长时间运行,不需要和其数据交互

使用stopService/stopself()停止服务

多次调用,onCreate方法只执行一次,onStartCommand多次执行

不与当前的Activity绑定,即使当前activity已经关闭了,服务也会急需运行

使用方法:

继承Service写一个类,实现自己的业务需要(onCreate、onStartCommand);

然后在清单文件中申明;

在activity里面通过startService来启动这个服务;

2、bindService:

特点:

需要和其进行数据交互,使用Binder类

使用unbindService停止服务

当activity销毁之后对应绑定的service自动停止、销毁

不能夸进程通信绑定

不能在广播中调用

使用方式:

继承Service写一个类,实现自己的业务需要(onCreate、onBind);

然后在清单文件中申明;

在activity里面通过bindService来启动这个服务,这里还需要一个参数,就是serviceConnection对象,通过这个对象来处理activity和service绑定的事件;

如果要相互通讯,还需要使用Binder:

继承自Binder来实现一个自己的Binder,在service的onBInd里面返回一个自己的Binder实例;

在activity的serviceconnection里面的onServiceConnected会把service里面的Binder的对象传递回来;我门可以在BInder里面,得到目标service的实例,这样,就可以和Service交互了。

那么,什么是IntentService?

IntentService:

特点:

会自动开启一个子线程,子线程任务结束以后,会自动stop,不需要手动去stopService或者stopself();

如果多次启动,会在一个队列中,依次的运行;

使用方法:

继承IntentService,实现自己的服务,然后重写onHandleIntent(),在里面做耗时操作;

intentService在启动的时候,需要一个默认的构造函数;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值