静态 注册的Broadcast Receiver怎么向Activity传递数据

来源:互联网 发布:财务软件 知乎 编辑:程序博客网 时间:2024/03/28 23:34

Broadcast Receiver:注册方式有两种,一种是静态的,一种是动态的。
对于动态的,在哪个Activity注册,就要在这个Activity取消注册,并且对于 其Context尽量不要使用getApplicationContext()方法,尽量使用注册该Broadcast Receiver的Context。这样,该Broadcast Receiver很容易和该Activity进行信息的传递,进而和其他Activity进行信息传递。比较简单,且易操作。
但是对于静态的,我理解为全局的Broadcast Recevier,首先要在AndroidManifest里进行注册,而对于和Activity进行信息传递则显得比较难办。

使用Handler比较容易解决,但是怎么在Boradcast Receiver中获得Activity的Handler?使用static handler 可以实现,但是带了了其他问题,不推荐。

刚开始我犯了一个低级错误,在这里也记一下吧:首先我注册了一个静态的Broadcast Receiver:

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.almoliu.bluechat">    <uses-permission android:name="android.permission.BLUETOOTH" />    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:supportsRtl="true"        android:theme="@style/AppTheme">        <activity            android:name=".Chat"            android:label="@string/app_name"            android:theme="@style/AppTheme.NoActionBar">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <activity android:name=".ScanDevices" />        <service            android:name=".ServerListener"            android:enabled="true"            android:exported="true" />        <receiver            android:name=".bluetooth_enable_receiver"            android:enabled="true"            android:exported="true">            <intent-filter>                <action android:name = "android.bluetooth.adapter.action.STATE_CHANGED"></action>                <category android:name="android.intent.category.DEFAULT"></category>            </intent-filter>        </receiver>    </application></manifest>

然后我写了一个class:

public  class bluetooth_enable_receiver extends BroadcastReceiver {    private static final String TAG = "bluetooth_enable_receiver";    public static final int BLUETOOTH_ENABLE_RECEIVER_MESS = 3001;    private Handler UiHandler;    private Context mContext;    public bluetooth_enable_receiver() {    }    public  bluetooth_enable_receiver(Context context,Handler handler) {        this.mContext = context;        UiHandler = handler;    }    @Override    public void onReceive(Context context, Intent intent) {        String action = intent.getAction();        if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {            if(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,-1)==BluetoothAdapter.STATE_OFF) {                Log.d("bluetooth receiver","onReceiver called...");                UiHandler.obtainMessage(BLUETOOTH_ENABLE_RECEIVER_MESS,null).sendToTarget();            }        }    }}

在MainActivity中定义了一个成员变量来获得这个类的一个实例,并在onCreate()方法中进行了初始化
mbluetooth_enable_receiver = new bluetooth_enable_receiver(this,UiHandler);
结果是这样的,bluetooth_enable_receiver的成员变量UiHandler一直是NULL,这说明系统在进行该Broadcast Receiver 声明定义时,并没有call自己定义的构造函数

public  bluetooth_enable_receiver(Context context,Handler handler) {        this.mContext = context;        UiHandler = handler;    }

可能实例也和MainActivity中的成员变量mbluetooth_enable_receiver不是同一个,至于具体的机制问题,麻烦大神解答下,所以这种方法是行不通的。

下面我在Broadcast中声明了一个Handler的静态成员变量,然后定义了一个静态成员方法,设置该成员变量,并在MainActivity进行初始化,结果是可以的,但是感觉不舒服。

 private static Handler UiHandler;  public static void setUiHandler(Handler handler) {        UiHandler= handler;  }在oncreate(): bluetooth_enable_receiver.setUiHandler(UiHandler);

后来在网上查到了两个Activity进行handler传递的方法,参考http://blog.csdn.net/jason0539/article/details/18055259
因为Intent不能传递object,所以 使用这种方法是可以实现传递Handler的,但是方法并不是最好的。
个人觉得利用公共类是最好的,另外可以使用Messenger来实现。

Activity1

package com.example.almoliu.handlerbetweenacti;import android.content.Intent;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.os.Messenger;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.Button;import android.widget.Toast;public class MainActivity extends AppCompatActivity {    Button next_btn;    public  static final int FLAG = 1001;    private Messenger messenger1;    private Handler UiHandler = new Handler() {        @Override        public void handleMessage(Message msg) {            switch (msg.what) {                case FLAG:                    Toast.makeText(MainActivity.this,"feafesaf",Toast.LENGTH_LONG).show();                    break;                default:                    super.handleMessage(msg);                    break;            }        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        messenger1 = new Messenger(UiHandler);        next_btn = (Button)findViewById(R.id.next_btn);        next_btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Intent i = new Intent(MainActivity.this,Main2Activity.class);                Bundle bundle = new Bundle();                bundle.putBinder("IBinder",messenger1.getBinder());                i.putExtras(bundle);                startActivity(i);            }        });    }}

Activity2

public class Main2Activity extends AppCompatActivity {    MyHandler mHandler1 = null;    Button send_btn;    private Messenger messenger2;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main2);        Intent  i = getIntent();        Bundle bundle = i.getExtras();        messenger2 = new Messenger(bundle.getBinder("IBinder"));        send_btn = (Button)findViewById(R.id.button);        send_btn.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Message msg = Message.obtain(null,MainActivity.FLAG);                try {                    messenger2.send(msg);                } catch (RemoteException e) {                    e.printStackTrace();                }            }        });    }}

还有一种方法是,在activity里启动一个service,将handler传递过去:
在activity

TaskService.start(uiHandler, this);

在该service内:

public static void start(Handler handler,Context context) {        uiHandler = handler;        mContext = context;        Intent startIntent = new Intent(context,TaskService.class);        context.startService(startIntent);    }    public static void stop(Context context) {        Intent stopIntent = new Intent(context,TaskService.class);        context.stopService(stopIntent);    }    @Override    public void onCreate() {        super.onCreate();        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();        if((mBluetoothAdapter==null)||(!mBluetoothAdapter.isEnabled())) {            stopSelf();            return;        }    }

公共类方法:

public class Task {    private Handler mHandler;    private Context mContext;    private int mTaskId;    public static final int TASK_ACCEPT_ON = 0;    public static final int TASK_CONNECT_ON = 1;    public static final int TASK_CHAT_ON =2;    public static final int TASK_REC_MESSAGE = 3;    public static final int TASK_SEND_MESSAGE = 4;    private Object[] parameter;    public Task(Handler handler,Context context,int taskId,Object[] parameter) {        this.mContext = context;        this.mHandler = handler;        mTaskId = taskId;        this.parameter = parameter;    }    public Handler getHandler() {        return mHandler;    }    public int getTaskId() {        return  mTaskId;    }    public Object getObject(int pos) {        if(pos<=parameter.length-1)            return parameter[pos];        else            return null;    }}

只需要在activity或者service里创建一个方法

  public static void newTask(Task task) {        synchronized (tasksList) {            tasksList.add(task);        }   }
0 0
原创粉丝点击