Android中多线程
- 1.继承Thread类,重写run方法;
- 2.实现Runnable接口,重写run方法;
- 3.通过Callable和FutureTask创建线程
- 4.通过线程池创建线程
- 5 .AsyncTask
- 6 .HandlerThread
- 7.IntentService
Activity.runOnUiThread(Runnable)- 8 AsyncQueryHandler
2)View.post(Runnable) ;View.postDelay(Runnable , long)
Android中多线程主要有Java和Android两种实现方式组成;Java中实现多线程的类在java.util.concurrent包下,主要有:继承Thread、实现Runnable接口、实现Callable< T >接口、
Java中多线程
(一) 、最简单实现多线程方式
继承Thread类和实现Runnable接口是Java入门级的新起线程的方法;最简单的匿名内部类实现方式;
new Thread(() -> { }).start();
Runnable runThread = () -> {};
runThread.run();
new Thread(new Runnable() {
@Override
public void run() {
}
}).start();
其中Thread类是实现Runnale的,并且Thread提供了诸多对线程的操作管理方法;
Runnable则是光杆司令interface一个,就连最基本的start都要借助其他类开始执行,谁让它是interface呢。可以startRunnable的有Thread的start方法、Executor实现类中execute方法、ExecutorService实现类中的submit方法;
(二)Callable< V >和Future< V >创建线程
先回顾一下Runnable和Callable< V >源码吧;
//Runnable 源码
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
//Callable<V>源码
public interface Callable<V> {
//返回V对象
V call() throws Exception;
}
在源码中:
Runnable 接口中声明返回值为Void的run方法;所以Runnable开启的线程犹如脱缰骏马任其驰骋难以掌控,结果导致两个问题:
1.无法直接获取到线程执行执行的结果;2.不能直接捕获线程执行中的异常;
正是由于Runnable的“无法无天”难以控制,所以Java中的Callable< v >应用而生;
在Callable< v >源码可以看到与Runnable不同的是Callable< v >接口引入泛型V,在声明的call函数返回V 并且抛出Exception真是应对Runnable中的连个问题。
先看Future源码吧;
//Future<V>源码
public interface Future<V> {
//取消这个线程 返回ture 取消成功;false 取消失败
boolean cancel(boolean mayInterruptIfRunning);
//判断该Future是否可以取消
boolean isCancelled();
//该Future是否完成
boolean isDone();
//获取该线程返回的结果,如果线程为执行完阻塞,等待执行完再返回
V get() throws InterruptedException, ExecutionException;
//获取该线程返回的结果,设置超时
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
Future只是定义规范接口,FutureTask是它一个实现类【有点类似List和ArrayList关系】,FutureTask同时实现RunnableFuture< V > 接口,RunnableFuture< V > 是实现了Runnable和Future< V > ; 因此FutureTask具备了Future的能力;
实现Callable< T >接口多线程例子
public static void main(String[] args) {
try {
//FutureTask启动线程
CallableMThread mThread = new CallableMThread();
FutureTask<String> task = new FutureTask<String>(mThread);
task.run();
//返回的String结果
String resualt = task.get();
System.out.println(resualt);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
//线程池submit开启多线程
try {
CallableMThread mThread = new CallableMThread();
ExecutorService threadPool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
Future<String> submit = threadPool.submit(mThread);
String resualt = submit.get();
System.out.println(resualt);
threadPool.shutdown();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
//内部类的实现Callable<V>开启新线程方式
class CallableMThread implements Callable<String> {
@Override
public String call() throws Exception {
// TO DO
return "ThreadID :" + Thread.currentThread().getId() + " ThreadRandom :" + (Math.random() * 1000);
}
}
AsyncTask多线程
AsyncTask就没什么好多讲的了直接看例子吧
public class MainActivity extends Activity {
@BindView(R.id.imageView)
ImageView imageView;
private String bUrl = "https://www.baidu.com/img/bd_logo1.png?qua=high&where=super";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
new AsyncThread().execute(bUrl);
}
public Bitmap downloadUrlBitmap(String bitmapUrl) {
Bitmap bitmap = null;
//String strUrl = "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1524503878682&di=98234ccb6ca81bfe209aef92e0888eed&imgtype=0&src=http%3A%2F%2Fimg5.pcpop.com%2FArticleImages%2F500x375%2F3%2F3542%2F003542587.jpg";
HttpURLConnection mHttpURLConnection = null;
try {
URL url = new URL(bitmapUrl);
mHttpURLConnection = (HttpURLConnection) url.openConnection();
mHttpURLConnection.setConnectTimeout(3000);
mHttpURLConnection.setRequestMethod("GET");
inputStream = mHttpURLConnection.getInputStream();
bufferedInputStream = new BufferedInputStream(inputStream, 4 * 1024);
bitmap = BitmapFactory.decodeStream(bufferedInputStream);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (mHttpURLConnection != null) {
mHttpURLConnection.disconnect();
}
CloseUtils.closeQuietly(inputStream);
CloseUtils.closeQuietly(bufferedInputStream);
}
return bitmap;
}
class AsyncThread extends AsyncTask<String,Integer ,Bitmap>{
@Override
protected Bitmap doInBackground(String... strings) {
return downloadUrlBitmap(bUrl);
}
//主线程中 异步任务之前
@Override
protected void onPreExecute() {
super.onPreExecute();
}
//主线程中 异步任务之后返回结果【doInBackground返回的结果】
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
imageView.setImageBitmap(bitmap);
}
//主线程中 【下载进度回调】
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
//主线程中 【异步任务取消回调】
@Override
protected void onCancelled(Bitmap bitmap) {
super.onCancelled(bitmap);
}
@Override
protected void onCancelled() {
super.onCancelled();
}
}
}
Java终止线程的方式
1.使用标志位,使线程正常退出,即run方法执行完正常退出;
2.使用stop方法终止线程,但是stop、suspend和resume都已经被Java列入过期方法中,可能产生不确定后果;
3.interrupt中断线程(与return结合使用);
4.抛出异常;
Java线程优先级
java线程的优先级继承性:Java线程优先级具有继承性,随机性
java 线程安全问题
1.变量安全;
方法内部是变量是安全,全局变量(没有关键字final修饰)是非安全
synchronized锁的释放:
synchronized不具有继承性
1.运行完成;
2.运行时抛出异常:
一、Handel消息传递机制
1.主线程Handler消息传递机制
Android 中Handler在作用和功能就不用多说了,个人浅薄认识Handler根本上也是通过共享数据实现线程通信的
;
Handler采用了类似[观察者模式]设计思想,主线程
中通过继承Handler成为观察者
,子线程
中借助Handler对象发布消息
,Looper
负责检测目标MessageQueue中的变化,如果目标Queue的size发生变化,立即通知观察者主线程并且把message传递给观察者主线程的调度者
,从而实现线程之间通信;
整个过程其实就借助共享变量Message实现消息传递的,而Looper是负责检测和传递,MessageQueue实现缓存策略。
2.子线程中的Handler传递消息
在开发中很场景是需要在子线程中处理繁杂的逻辑,这个时候在子线程结合Handler就很好解决问题了,在Android主线程中默认为Handler时需要开启Looper,不停去MessageQueue读取Message,实现Message的及时处理;所以在子线程就需要手动实现Looper;例如在run方法中通过 Looper.prepare()和Looper.loop()即可实现。当然了这么ease的场景Google开发人员早就考虑到这一点了,所以HandlerThread就现身了;HandlerThread也是继承Thread,然后实现Looper,并且实现一些很简单的功能;HandlerThread源码总共才几十行而已一眼就看明白了;
子线程中的Handler的应用
public class MainActivity extends Activity {
@BindView(R.id.action_a)
Button actionA;
@BindView(R.id.action_b)
Button actionB;
private TestThread testThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
initThread();
initHandlerThread()
}
//创建子线程实现Handel
private void initThread(){
//创建子线程
testThread = new TestThread();
testThread.start();
}
//创建HandlerThread
private void initHandlerThread(){
HandlerThread handlerThread = new HandlerThread("HandlerThread",Thread.NORM_PRIORITY);
handlerThread.start();
mThreadHandler = new Handler(handlerThread.getLooper()) {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//TODO OTHRER
}
}
};
}
@OnClick({R.id.action_a, R.id.action_b})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.action_a:
//向TestThread线程Handler发消息
testThread.handler.sendEmptyMessage(0);
break;
case R.id.action_b:
//向ThreadHandler线程Handler发消息
mThreadHandler.sendEmptyMessage(1);
break;
}
}
//子线程
class TestThread extends Thread {
public Handler handler;
@SuppressLint("HandlerLeak")
@Override
public void run() {
Looper.prepare();
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//TODO OTHRER
}
};
Looper.loop();
}
}
}