Bundle

2018-07-05  本文已影响0人  小声音大世界

1.新建一个Bundle类
  Bundle bundle=new Bundle();
2.Bundle类中放入数据(key-value的形式,另一个Activity里面取数据的时候,通过key值找出对应的value值)
  bundle.putString("key" ," value");
3.新建一个intent对象,并将该bundle加入到这个intent对象
  Intent intent=new Intent( );
  intent.putExtras(bundle);
4.获取key所对应的value
  Bundle bundle=getIntent().getExtras();
  String data=bundle.getString("key");

Bundle是一个简单的数据携带包,该对象也包含了多个方法来存入数据:

putXxx(String key, Xxx data):向Bundle中放入Int、Long等各种类型的数据
putSerializable(String key, Serializable data):向Bundle中放入一个可序列化的对象

取出Bundle数据携带包里的数据的方法:

getXxx(String key):从Bundle取出Int、Long等各种类型的数据
getSerializable(String key,Serializable data):从Bundle取出一个可序列化的对象


项目中使用:Bundle

1.消费完以后把信息存到bundle中,发送到handler中

    Bundle bundle =new Bundle();
    bundle.putBoolean("Recharge", Consume.HashRecharge);
    bundle.putString("card_id",String.format("%0"+10+"d", Long.valueOf(Consume.CardId , 16)));
    bundle.putString("studentname", Consume.studentname);
    bundle.putString("balance", String.valueOf(Consume.balance));//balance是余额
    bundle.putString("notification","2+  扣费成功");
    bundle.putString("url", ActivityContents.QR_forPay+"/card_num/"+Consume.CardId);

    //ActivityContents.ConsumeResultNoOverTime = 26 是handler功能
    Message.obtain(handler,ActivityContents.ConsumeResultNoOverTime,bundle).sendToTarget();

2.在handler中处理消息

private void InitHandler(){
     mHandler = new Handler() {
           public void handleMessage(Message msg) {
               switch(msg.what){
                    case ActivityContents.CostShowNoOverTime:
                            Bundle bun=(Bundle)msg.obj;

        notification_text.setText(bun.getString("notification"));
        balance_text.setText(bun.getString("balance"));
        student_name.setText(bun.getString("studentname"));
        student_cardId.setText(bun.getString("card_id"));
        textcost.setText(bun.getDouble("sum")+"元");
        if(!bun.getString("notification").equals("请于感应区刷卡")){
            mSerialdriver.McuShow(mSerialdriver.Action_StudentMessage, bun.getString("balance","0")+"+"+
                    bun.getString("studentname"," "));          
            mSerialdriver.McuShow(mSerialdriver.Action_MessageFailShow, bun.getString("notification"));
            }
        break;
           }
      };
}

Handler

Handler既是发送者也是接收处理者,一个消息发送出来,交由哪个Handler去处理,这个完全取决于这个消息的发送者是哪个Handler。即一个Handler发送的消息,只能交由自己去处理。要做到异步线程进行通信,关键在于在A线程中拿到B线程的Handler,拿到之后就可以使用B线程的Handler去发送消息,交由B线程去处理消息了。线程与Handler之间是多对一的关系,一个线程可以有多个Handler,一个Handler只能且必须绑定一个线程。一个线程有多个Handler(使用场景会在后面介绍),用于处理不用类型的消息。
使用Handler的表现形式有两种:

需要注意的是:(1)该Runnable也会被包装成一个消息的形式进行传递。(2)整个过程并没有另外新建线程,该Runnable在Handler所在线程执行

如何使用 :

1.创建 Handler

private Handler handler = new Handler() {
 // 重写 handleMessage 来根据不同 what 来处理 Message
// 这个方法在 Handler 创建的线程执行
@Override public void handleMessage(Message msg) {
    super.handleMessage(msg);
    switch (msg.what) {
        case 0:
          MLog.i(msg.obj);
          break;
        case 1:
          break;
        default:

        }
    }
};

2.创建并发送 Message

// 获取一个 Message
Message message = Message.obtain();
message.what = 0;
message.obj = new Object();
// 使用 Handler 发送 Message
// 消息发送完成后 Handler 的 handleMessage(Message msg) 会处理消息
handler.sendMessage(message);

// 延迟 1s 发送 Message
handler.sendMessageDelayed(message, 1000);
// 发送一个空的 Message
handler.sendEmptyMessage(msg.what);  
// 延迟发送一个空的 Message
handler.sendEmptyMessageDelayed(0, 1000);

// 还可以这样
// 创建 Message 并绑定 Handler
Message message = handler.obtainMessage();
message.what = 0;
message.obj = new Object();

// 发送 Message
message.sendToTarget();

3.使用 Handler 子线程请求数据,主线程刷新 UI

// 1. 在主线程创建 Handler(略)
// 2. 子线程请求数据,主线程刷新 UI
new Thread(new Runnable() {
    @Override public void run() {
      // 获取网络数据
     final List<Object> datas = getNetData();

        // 方法一:将数据作为 Message 的 obj 发送出去,在 handleMessage 中刷新 UI
        Message msg = Message.obtain();
        msg.what = 1;
        msg.obj = data;
        handler.sendMessage(msg);

        // 方法二:直接在 post 中刷新 UI
        handler.post(new Runnable() {
             @Override public void run() {
             // 使用 datas 刷新 UI
            // 这个方法也会在 Handler 创建的线程执行
            }
     });
    }
}).start();

项目中使用

1.在MainActivity中

public  static Handler mHandler;

public   PictureThread mPictureThread;//上传图片推送线程
private SerialPortDriver mSerialdriver;//串口通信线程

onCreate()

startThreads();

InitHandler();


//1.创建 Handler
private void InitHandler(){
     mHandler = new Handler() {
           public void handleMessage(Message msg) {
               switch(msg.what){
                    case ActivityContents.MobileNetwork:
                break;
                    case ActivityContents.NetworkOFF:
                break;
                    case ActivityContents.ConsumeResult:
                    //那边发来的消费结果这里处理:
                    
                break;

                }
           }
      };
}


//开启线程
private void startThreads(){
    mPictureThread = new PictureThread(mContext); //上传图片推送接口
    new Thread(mPictureThread).start();
  
    mSerialdriver = new SerialPortDriver(context);  //串口通信线程
    new Thread(mSerialdriver).start();
}

2.在SerialPortDriver中,这是处理单片机传进来的类。这个类 通过实现Runnable接口创建线程

知识点
通过实现Runnable接口创建线程
(1).定义一个类实现Runnable接口,重写接口中的run()方法。在run()方法中加入具体的任务代码或处理逻辑。
(2).创建Runnable接口实现类的对象。
(3).创建一个Thread类的对象,需要封装前面Runnable接口实现类的对象。(接口可以实现多继承)
(4).调用Thread对象的start()方法,启动线程

public class SerialPortDriver implements Runnable,Global{
private Handler handler;
private Message msg=null;
private Bundle bundle=null;

    public SerialPortDriver(Context context) {
        this.handler=MainActivity.getHandler();
        Message.obtain(handler,RecordShow,2).sendToTarget();

        mReadThread = new ReadThread();
        mReadThread.start();
    }

    @Override
public void run() {
    addFirstAnsTask(new picTask(AnswerBuffer));
}

private class ReadThread extends Thread{
    
    @Override
    public void run() {
        super.run();
        Message.obtain(handler,ActivityContents.ConsumeResult,bundle).sendToTarget();
        //handler在这里发送消息,此handler是: this.handler=MainActivity.getHandler();
    }
}

extends Thread 与 implements Runnable 的区别
(1).首先定义一个类去继承Thread父类,重写父类中的run()方法。在run()方法中加入具体的任务代码或处理逻辑。
(2).直接创建一个ThreadDemo2类的对象,也可以利用多态性,变量声明为父类的类型。
(3).调用start方法,线程t启动,隐含的调用run()方法。

两种方式的比较

首先分析两种方式的输出结果,同样是创建了两个线程,为什么结果不一样呢?
使用实现Runnable接口方式创建线程可以共享同一个目标对象(TreadDemo1 tt=new TreadDemo1();),实现了多个相同线程处理同一份资源。

采用继承Thread类方式:
(1)优点:编写简单,如果需要访问当前线程,无需使用Thread.currentThread()方法,直接使用this,即可获得当前线程。
(2)缺点:因为线程类已经继承了Thread类,所以不能再继承其他的父类。
采用实现Runnable接口方式:
(1)优点:线程类只是实现了Runable接口,还可以继承其他的类。在这种方式下,可以多个线程共享同一个目标对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将CPU代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。
(2)缺点:编程稍微复杂,如果需要访问当前线程,必须使用Thread.currentThread()方法

3.使用 Handler 子线程请求数据,主线程刷新 UI

//开启线程
private void startThreads(){
    mPictureThread = new PictureThread(mContext); //上传图片推送接口
    new Thread(mPictureThread).start();
  
    mSerialdriver = new SerialPortDriver(context);  //串口通信线程
    new Thread(mSerialdriver).start();
}

sendToTarget与sendMessage的区别

1、 message 从handler 类获取,从而可以直接向该handler 对象发送消息。target就是创建message的handler

Message msg = handler.obtainMessage();
msg.sendToTarget();

2、new出来的message或者通过Message.obtain的方式创建的message,可直接调用 handler 的发送消息方法来发送消息。

Message msg=new Message();
//Message msg= Message.obtain();
handler.sendMessage(msg);

示例:

/*1、message由handler创建,可直接向handler发送消息。msg.sendToTarget()*/
        Message msg = handler.obtainMessage();
        msg.arg1 = i;
        msg.sendToTarget();

/*2、message通过new的方式创建,可用handler.sendMessage(msg)来发送消息*/
        Message msg=new Message();
        msg.arg1=i;
        handler.sendMessage(msg);
        //直接调用 handler 的发送消息方法发送消息。

/* 3、message通过Message.obtain的方式创建,可用sendMessage(msg)来发送消息 */
       Message msg= Message.obtain();
       msg.arg1=i;
       handler.sendMessage(msg);
上一篇下一篇

猜你喜欢

热点阅读