android java 线程通信_Android 线程间通信

进程与线程的区别?

在Android中,线程是跑在进程之中的,当手机打开一个APP就相当于打开了一个进程,比如:UI界面的更新,就是在主线程中完成的,我也可以自定义一些子线程来完成所需要的任务.

如何创建线程?创建线程的几种方式?

1.创建一个类继承Thread类

2.创建一个类实现Runnable接口

什么是多线程?

线程是程序中一个单一的顺序控制流程,在程序中同是运行多个线程完成不同的工作,称为多线程

ANR的基础知识及产生?

ANR:application not responding :应用程序无响应

产生的情况:1.主要类型按键或触摸事件在特定的时间(5秒)内无响应

2.BroadcastReceiver在特定事件(10秒)内无法处理完成

3.小概率类型Service在特定事件内无法完成

线程的状态:

创建(new) ---->就绪(runnable)---->运行(running)---->阻塞(bloocked)----->消亡(dead)

当线程满足所需要运行的条件时,才能进入就绪状态

当线程就如就绪状态后,不能马上获得cpu的执行时间,需要CPU进行资源分配

当线程被中断后执行完毕才会被消亡

线程的生命周期

1c37b6c6916fb35dd9b3cc52ed232682.png

注意:多线程会导致CPU资源分配的增加导致系统繁忙

多线程示例:售票

packagecom.hejun.ticket;importandroid.support.v7.app.AppCompatActivity;importandroid.os.Bundle;importandroid.util.Log;importandroid.view.View;importandroid.widget.Button;public class MainActivity extendsAppCompatActivity {final static String TAG = "MainActivity";privateButton button;

@Overrideprotected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

button=findViewById(R.id.strat_sale);

button.setOnClickListener(newView.OnClickListener() {

@Overridepublic voidonClick(View view) {

SaleTickets saleTickets1= new SaleTickets(4);

SaleTickets saleTickets2= new SaleTickets(3);

SaleTickets saleTickets3= new SaleTickets(2);

SaleTickets saleTickets4= new SaleTickets(2);

saleTickets1.setName("售票窗口1");

saleTickets2.setName("售票窗口2");

saleTickets3.setName("售票窗口3");

saleTickets4.setName("售票窗口4");

saleTickets1.start();

saleTickets2.start();

saleTickets3.start();

saleTickets4.start();

}

});

}private class SaleTickets extendsThread{private inttickets;private SaleTickets(inttickets){this.tickets =tickets;

}

@Overridepublic voidrun() {super.run();while(tickets>0){

Sale();

}

Log.d(TAG, Thread.currentThread().getName()+ "的票售卖完了");

}private voidSale(){

tickets--;

Log.d(TAG, Thread.currentThread().getName()+ "正在卖票,还剩下"+ tickets +"张票");

}

}

}

演示结果

7cdd95d50791cf9de011581e40fee7d6.png

线程间通信的相关组件

1.Message :消息.其中包含了消息ID,消息处理对象以及处理数据,Message有MessagesQueue统一列队,最终有Handle处理

2.Handle:处理者,负责Message的发送及处理,实现handleMessage(Message msg)方法,对特定的MEssage进行处理

3.MessagesQueue:消息队列,用来存放Handle发送过来的消息,并按照先进先出规则执行

4.Looper:消息泵,不断的从MessagesQueue中抽取Message执行,一个MessagesQueue需要一个Looper

5.Thread:线程,辅助调度整个消息循环,即消息循环执行的场所

关系:Handle looper  MessagesQueue是简单的三角关系Looper和MessagesQueue是一一对应的

16df13b33e06910d2b722cadb088c232.png

消息循环

一个Message经由Handle发送到MessagesQueue队列中,再由Looper不断的从MessagesQueue抽取,又再一次回到Handle的环抱,实现线程间的通信

线程与更新

在ui线程中,如果创建Handle是不传入Looper对象,那么将直接使用UI\线程的Looer对象(系统已经帮我们自动创建了),在其他线程创建Handle如果不传入Looper对象,那么Handle将不能接收处理消息,在这种情况下,通常的做法是:

840b6b1c62f08ba37a7ffe955b4393a3.png

在创建Handle之前,为该线程准备好一个Looper(Looper.prepare),然后让这个Looper跑起来(Looper.loop),这样Handle 才能正常工作;.

注意:Handle处理消息总是在创建Handler的线程中执行,而我们的消息处理,不乏UI的更新操作,不正确的线程直接更新UI将引发异常,因此,我们需要时刻关心Handler是在哪个线程中创建的.

SDk提供四中方式可以从其他线程中访问UI线程

1.Activity.runOnUiThread(Runnable)

2.View.post(Runnable)

3.View.postDelayed(Runnable,long)

4.Handler

案例,从网上下载图片并更新进度

packagecom.hejun.ticket;importandroid.annotation.SuppressLint;importandroid.app.ProgressDialog;importandroid.graphics.Bitmap;importandroid.graphics.BitmapFactory;importandroid.os.Handler;importandroid.os.Message;importandroid.os.SystemClock;importandroid.os.Trace;importandroid.support.v7.app.AppCompatActivity;importandroid.os.Bundle;importandroid.util.Log;importandroid.view.View;importandroid.widget.Button;importandroid.widget.ImageView;importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;importjava.net.HttpURLConnection;importjava.net.MalformedURLException;importjava.net.URL;public class DownPicture extendsAppCompatActivity {final static String address = "http://img4.imgtn.bdimg.com/it/u=1952016862,1880307894&fm=26&gp=0.jpg";private static final String TAG = "DownPicture";private Handler mMainHandler = null;private intprogress;

@Overrideprotected voidonCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);

setContentView(R.layout.activity_down_picture);

Button button=findViewById(R.id.button);final ImageView imageView =findViewById(R.id.img);

button.setOnClickListener(newView.OnClickListener() {

@SuppressLint("HandlerLeak")

@Overridepublic voidonClick(View view) {final ProgressDialog progressDialog = new ProgressDialog(DownPicture.this);

progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);

progressDialog.setMessage("下载中");

progressDialog.setMax(100);

progressDialog.show();new Thread(new Down(),"下载图片").start();

mMainHandler= newHandler(){

@Overridepublic voidhandleMessage(Message msg) {super.handleMessage(msg);switch(msg.what){case 10010:

progressDialog.setProgress(msg.arg1);break;case 10011:

progressDialog.dismiss();

Bitmap bitmap=(Bitmap) msg.obj;

imageView.setImageBitmap(bitmap);break;

}

}

};

}

});

}class Down implementsRunnable {

String fileName= "dowmPicture";

@Overridepublic voidrun() {try{

URL url= newURL(address);

HttpURLConnection httpURLConnection=(HttpURLConnection) url.openConnection();

httpURLConnection.setConnectTimeout(5000);

httpURLConnection.setRequestMethod("GET");if (httpURLConnection.getResponseCode() ==HttpURLConnection.HTTP_OK) {

InputStream inputStream=httpURLConnection.getInputStream();

OutputStream outputStream=openFileOutput(fileName, MODE_PRIVATE);byte[] bytes = new byte[1024*1024];int s =httpURLConnection.getContentLength();int d = 0;int curent = 0;while ((d = inputStream.read(bytes)) != -1){

outputStream.write(bytes,0,s);

curent+=d;

progress= (int) ((float)curent/s*100);

Log.d(TAG,"当前现在进度为" +progress);

SystemClock.sleep(40);

Message message= newMessage();

message.arg1=progress;

message.what= 10010;

mMainHandler.sendMessage(message);

}if (progress == 100){

Bitmap bitmap=BitmapFactory.decodeFile(getFileStreamPath(fileName).getAbsolutePath());

Message message= newMessage();

message.obj=bitmap;

message.what= 10011;

mMainHandler.sendMessage(message);

}

inputStream.close();

outputStream.close();

httpURLConnection.disconnect();

}

}catch(MalformedURLException e) {

e.printStackTrace();

}catch(IOException e) {

e.printStackTrace();

}

}

}

}

9b90b906a0c3abe19a5849ed27882693.png

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值