一,Handler
二,AsyncTask
一,Asynctask是什么
是处理异步任务类。
本质封装了线程池和Handler的异步框架。
二,使用方法
三个参数和五个方法
三,Asynctask内部原理
Asynctask内部封装了线程池来执行耗时任务,当任务执行完毕后通过handler通知主线程。
四,Asynctask注意事项
1,内存泄漏:非静态的Asynctask本身持有Act的对象。这样有可能造成没错泄露。
处理方法和处理Handler没存泄露方法一样。
处理方法:使用弱引用,使用静态内部类。
2,生命周期:在Activity中的onDestroy中调用AsyncTask cancel方法。否则可能出现崩溃现象。
3,结果丢失:在Activity被回收或者屏幕旋转的时候导致之前AsyncTask持有持有的返回值无法刷新Activiy.从而结果丢失。
4,穿行or并行:1.6之前是穿行的。在1.6到2.3是并行的。在2.3以后是穿行的,但是也可以执行并行。
//默认的使用的是串行操作
asyncTask.execute(imageUrl)
//下面的设置是并行执行操作
asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,imageUrl)
Asynctask处理耗时比较短的操作,处理不了高并发。为什么???
AsyncTask使用示例
public class MyAsyncTask extends AsyncTask<String,Integer,Bitmap> {
IResultCallBack mCallBack;
public MyAsyncTask(IResultCallBack callBack) {
mCallBack = callBack;
}
@Override
protected Bitmap doInBackground(String... params) {
publishProgress(100);//在任务线程中根据具体的进度返回进度值大小
return downloadUrlBitmap(params[0]);
}
@Override
protected void onProgressUpdate(Integer... values) {
//此方法在主线程中调用
//values就是publishProgress返回的值。
}
@Override
protected void onPostExecute(Bitmap result) {
//在UI中调用,返回结果
mCallBack.ResultCallback(result);
}
@Override
protected void onCancelled(Bitmap result) {
super.onCancelled(result);
}
@Override
protected void onCancelled() {
super.onCancelled();
}
@Override
protected void onPreExecute() {
//在执行异步操作的时候调用。
super.onPreExecute();
}
interface IResultCallBack {
public void ResultCallback(Bitmap result);
}
private Bitmap downloadUrlBitmap(String urlString) {
HttpURLConnection urlConnection = null;
BufferedInputStream in = null;
Bitmap bitmap = null;
try {
final URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream(), 8 * 1024);
bitmap = BitmapFactory.decodeStream(in);
} catch (final IOException e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
try {
if (in != null) {
in.close();
}
} catch (final IOException e) {
e.printStackTrace();
}
}
return bitmap;
}
}
Activity中的实现
class AsyncTaskActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_async_task)
var imageView = findViewById<ImageView>(R.id.imageview)
findViewById<Button>(R.id.btn1).setOnClickListener {
var imageUrl = "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fwww.08lr.cn%2Fuploads%2Fallimg%2F170513%2F1-1F513164126.jpg&refer=http%3A%2F%2Fwww.08lr.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1615345183&t=c11176a5623e95b8cb0c1c58a5ec8094"
var asyncTask = MyAsyncTask(MyAsyncTask.IResultCallBack {
imageView.setImageBitmap(it)
})
//asyncTask.execute(imageUrl)
//asyncTask.cancel(true)
asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,imageUrl)//可以通过设置执行的形式。串行or并行。
}
findViewById<Button>(R.id.btn2).setOnClickListener {
}
findViewById<Button>(R.id.btn3).setOnClickListener {
}
}
}

参考问题:
ArrayDeque:https://www.cnblogs.com/chenglc/p/10722304.html
AtomicInteger:https://www.cnblogs.com/zhi-xing/p/10445234.html
三,HandlerThread
Android开发——HandlerThread以及IntentService详解
使用示例
创建下载任务管理类
public class DownLoadTaskManager {
HandlerThread handlerThread;
Handler handler;
public DownLoadTaskManager() {
handlerThread = new HandlerThread("download_thread");
handlerThread.start();
handler = new Handler(handlerThread.getLooper());
}
public void download(String downloadUrl) {
handler.post(new Runnable() {
@Override
public void run() {
downLoadTask(downloadUrl);
}
});
}
/**
* 模拟耗时的下载任务
*
* @param downloadUrl 下载地址
*/
public void downLoadTask(String downloadUrl) {
int dataCount = 10;
for (int i = 1; i <= dataCount; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Logs.iprintln("DownloadTask", downloadUrl + " 进度 =" + (100 * i / dataCount) + "%");
}
}
public void quit() {
//清空消息队列中的消息。Api1就支持
handlerThread.quit();
}
public void quitSafely() {
//清空消息队列中的延时消息。Api18才支持
handlerThread.quitSafely();
}
public int getThreadId() {
return handlerThread.getThreadId();
}
}
Activity插入下载任务
class HandlerThreadActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_handler_thread)
var downLoadM = DownLoadTaskManager()
findViewById<Button>(R.id.button1).setOnClickListener {
downLoadM.download("task1")
downLoadM.download("task2")
downLoadM.download("task3")
downLoadM.download("task4")
downLoadM.download("task5")
downLoadM.download("task6")
}
findViewById<Button>(R.id.button2).setOnClickListener {
Logs.eprintln("", "DownloadTask get HandlerThread getThreadId " + downLoadM.threadId)
if (downLoadM.threadId != -1) {
downLoadM.quit()
}
}
findViewById<Button>(R.id.button3).setOnClickListener {
Logs.eprintln("", "DownloadTask get HandlerThread getThreadId " + downLoadM.threadId)
}
}
}
四,IntentServer
- 它本质是一种特殊的Service,继承自Service并且本身就是一个抽象类
- 它可以用于在后台执行耗时的异步任务,当任务完成后会自动停止
- 它拥有较高的优先级,不易被系统杀死(继承自Service的缘故),因此比较适合执行一些高优先级的异步任务
- 它内部通过HandlerThread和Handler实现异步操作
- 创建IntentService时,只需实现onHandleIntent和构造方法,onHandleIntent为异步方法,可以执行耗时操作
示例
实现IntentService类
public class IntentServerImpl extends IntentService {
private static String TAG = "IntentServerImpl";
public IntentServerImpl() {
super("test_thread_name");
}
public static final String DOWNLOAD_URL = "download_url";
public static final String INDEX_FLAG = "index_flag";
public static UpdateUI updateUI;
public static void setUpdateUI(UpdateUI updateUIInterface) {
updateUI = updateUIInterface;
}
/**
* 实现异步任务的方法
*
* @param intent Activity传递过来的Intent,数据封装在intent中
*/
@Override
protected void onHandleIntent(Intent intent) {
//在子线程中进行网络请求
Bitmap bitmap = downloadUrlBitmap(intent.getStringExtra(DOWNLOAD_URL));
Message msg1 = new Message();
msg1.what = intent.getIntExtra(INDEX_FLAG, 0);
msg1.obj = bitmap;
//通知主线程去更新UI
if (updateUI != null) {
updateUI.updateUI(msg1);
}
//mUIHandler.sendMessageDelayed(msg1,1000);
Logs.eprintln(TAG, "onHandleIntent");
}
@Override
public void onCreate() {
Logs.eprintln(TAG, "onCreate");
super.onCreate();
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Logs.eprintln(TAG, "onStart");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Logs.eprintln(TAG, "onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Logs.eprintln(TAG, "onDestroy");
super.onDestroy();
}
public interface UpdateUI {
void updateUI(Message message);
}
private Bitmap downloadUrlBitmap(String urlString) {
HttpURLConnection urlConnection = null;
BufferedInputStream in = null;
Bitmap bitmap = null;
try {
final URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream(), 8 * 1024);
bitmap = BitmapFactory.decodeStream(in);
} catch (final IOException e) {
e.printStackTrace();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
try {
if (in != null) {
in.close();
}
} catch (final IOException e) {
e.printStackTrace();
}
}
return bitmap;
}
}
在AndroidManifest中添加Service标签。
<application
...>
<service android:name=".ui.handler.IntentHandler.IntentServerImpl"/>
</application>
Activity中添加下载任务。
class IntentHandlerActivity : AppCompatActivity(), IntentServerImpl.UpdateUI {
private val TAG = "IntentServerImpl"
private lateinit var act:IntentHandlerActivity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_intent_handler)
act = this
var list = ArrayList<String>()
list.add("https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3795757253,2048194183&fm=26&gp=0.jpg")
list.add("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.redocn.com%2Ftupian%2F20140910%2Fchangfazhongfenmeinvzhaopian_3014557.jpg&refer=http%3A%2F%2Fimg3.redocn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614682734&t=e24351c88bb4d2f2eafba51bb64e2edc")
list.add("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg01.taopic.com%2F161120%2F235110-161120135U733.jpg&refer=http%3A%2F%2Fimg01.taopic.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614682734&t=9b2b02b684988874f8645bffa1661f13")
list.add("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fattachments.gfan.net.cn%2Fforum%2Fattachments2%2F201301%2F27%2F2025395o1m44co41oxgk9d.jpg&refer=http%3A%2F%2Fattachments.gfan.net.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614682734&t=2414401f88da3e301d62b8bff850f31f")
list.add("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic1.win4000.com%2Fmobile%2F2019-01-30%2F5c511a2c0dc0d.jpg&refer=http%3A%2F%2Fpic1.win4000.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614682734&t=1a5f5227d674fbcfef7f6958843c33ac")
list.add("https://ss0.bdstatic.com/70cFvHSh_Q1YnxGkpoWK1HF6hhy/it/u=1923476360,102453652&fm=26&gp=0.jpg")
list.add("https://ss0.baidu.com/94o3dSag_xI4khGko9WTAnF6hhy/zhidao/pic/item/a50f4bfbfbedab647331f9dff436afc379311e69.jpg")
list.add("https://gimg2.baidu.com/image_search/src=http%3A%2F%2F01.minipic.eastday.com%2F20170207%2F20170207145729_d643e7de3fcaf066fe54e19b3293e074_4.jpeg&refer=http%3A%2F%2F01.minipic.eastday.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614682734&t=1a053aee259a1e9054496b996e1a1798")
list.add("https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3030325702,1144960403&fm=26&gp=0.jpg")
list.add("https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.daimg.com%2Fuploads%2Fallimg%2F150124%2F3-150124224208.jpg&refer=http%3A%2F%2Fimg.daimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1614682850&t=2ac188c245112357f916b0c70929c9c3")
findViewById<Button>(R.id.btn_start_download).setOnClickListener {
Logs.eprintln(TAG," Onclick btn_start_download")
var intent = Intent(act, IntentServerImpl::class.java)
for (i in 0 until list.size) {
Logs.eprintln(TAG," for index=$i")
intent.putExtra(IntentServerImpl.DOWNLOAD_URL, list[i])
intent.putExtra(IntentServerImpl.INDEX_FLAG, i)
startService(intent)
}
}
IntentServerImpl.setUpdateUI(this)
}
private val mUIHandler: Handler = object : Handler() {
override fun handleMessage(msg: Message) {
findViewById<ImageView>(R.id.imageview).setImageBitmap(msg?.obj as Bitmap)
}
}
override fun updateUI(message: Message?) {
Logs.eprintln(TAG,"message.what=${message?.what} message.obj=${message?.obj}")
message?.let {
mUIHandler.sendMessage(message)
}
}
}
网友评论