上面学习了线程通过Massage发送字符串消息,Handler接收字符串消息,这样的形式来更新ui,接下来,一起分享怎么把一个对象利用消息机制发送出去,让主线程接收来更新ui。
下面就利用一个服务Server,Handler,Activity,和一个对象类分享具体实现情况。
首先创建一个个类,什么都行。例如:
1 package dfrz.me.android.pcfileshare.bean; 2 3 import java.io.Serializable; 4 5 /** 6 * 描述:广告信息</br> 7 */ 8 public class ADInfo implements Serializable{ 9 10 String id = ""; 11 String url = ""; 12 String content = ""; 13 String type = ""; 14 15 public String getId() { 16 return id; 17 } 18 19 public void setId(String id) { 20 this.id = id; 21 } 22 23 public String getUrl() { 24 return url; 25 } 26 27 public void setUrl(String url) { 28 this.url = url; 29 } 30 31 public String getContent() { 32 return content; 33 } 34 35 public void setContent(String content) { 36 this.content = content; 37 } 38 39 public String getType() { 40 return type; 41 } 42 43 public void setType(String type) { 44 this.type = type; 45 } 46 47 }
创建一个Activity父类:
import java.util.ArrayList; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.util.Log; import android.view.Window; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.Toast; import dfrz.me.android.pcfileshare.service.MyHandler; import dfrz.me.android.pcfileshare.service.MyService; public abstract class CustomActivity extends Activity { public static final int LENGTH_LONG = 1; public static final int LENGTH_SHORT = 0; public static String LOGCAT_KEY = "folder"; public static ArrayList<CustomActivity> activityList = new ArrayList<CustomActivity>(); public InputMethodManager inputMethodManager; protected MyService.MyBinder binder = null; private ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { Log.d("file", "privateChat-->onServiceDisconnected"); } @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.d("file", "privateChat-->onServiceConnected"); binder = (MyService.MyBinder) service; } }; public void toast(String str,int i){ Toast.makeText(getApplicationContext(),str,i).show(); } /** * onCreate方法中绑定服务。 * 添加接口等等一些操作。 * @param savedInstanceState */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //getSupportActionBar().hide(); requestWindowFeature(Window.FEATURE_NO_TITLE); // 启动activity时不自动弹出软键盘 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); //获取系统键盘对象 inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); //将这个Activity加入到消息接收队列中 MyHandler.getInstance().registerActivity(this); activityList.add(this); try { while (!bindService(new Intent(this, MyService.class), connection, BIND_AUTO_CREATE)) ; } catch (Exception e) { Toast.makeText(this, "服务器连接失败!", Toast.LENGTH_SHORT).show(); } } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); try { //移除队列 MyHandler.getInstance().unRegisterActivity(this); activityList.remove(this); unbindService(connection); } catch (Exception e) { e.printStackTrace(); } } public static void finishAll() { for (Activity activity : activityList) { if (!activity.isFinishing()) { activity.finish(); } } } /** * 初始化UI */ protected abstract void initView(); /** * 初始化数据 */ protected abstract void initData(); /** * 监听事件 */ protected abstract void initOnClick(); /** * 接收消息 * @param bundle */ public abstract void recvMessageFormHandler(Bundle bundle); }
编写自己的Handle消息接收,和广播到每个活动界面上,前提是每个Activity都要继承父类,并实现接收消息的方法。
1 2 import android.os.Bundle; 3 import android.os.Handler; 4 import android.os.Message; 5 import android.util.Log; 6 7 import java.util.ArrayList; 8 9 import dfrz.me.android.pcfileshare.base.CustomActivity; 10 11 /** 12 * Created by Administrator on 2016/11/18. 13 */ 14 public class MyHandler extends Handler { 15 private ArrayList<CustomActivity> activityList; 16 17 private Bundle bundle; 18 private MyHandler(){ 19 activityList = new ArrayList<CustomActivity>(); 20 } 21 22 private static MyHandler instance = null; 23 24 @Override 25 public void handleMessage(Message msg) { 26 // TODO Auto-generated method stub 27 super.handleMessage(msg); 28 bundle = msg.getData(); 29 try { 30 if(activityList.size()>0){ 31 for(CustomActivity customActivity:activityList){ 32 //向每个customActivity内发送消息 33 customActivity.recvMessageFormHandler(bundle); 34 } 35 } 36 } catch (Exception e) { 37 // TODO: handle exception 38 } 39 } 40 41 public static MyHandler getInstance(){ 42 if(instance == null){ 43 instance = new MyHandler(); 44 } 45 return instance; 46 } 47 public void registerActivity(CustomActivity activity) 48 { 49 Log.d("HANDLER", "add "+activity.toString()); 50 activityList.add(activity); 51 } 52 public void unRegisterActivity(CustomActivity activity){ 53 Log.d("clientApp","remove"+activity.toString()); 54 activityList.remove(activity); 55 } 56 }
为了方便发送不同的对象消息数据,封装发送消息方法:
1 import android.os.Bundle; 2 import android.os.Message; 3 4 import java.io.Serializable; 5 6 /** 7 * Created by Administrator on 2017/1/16. 8 */ 9 10 public class SendHandlerMsg { 11 12 private static Message message; 13 14 /** 15 * 建立bundle 向 fragment 中发送消息 16 * 17 * @param SerializableKey 系列化键值 18 * @param obj 消息内容,传入时必须先系列化对象,不然数据发送不出去,会导致堵塞异常 19 * 建立bundle 向 Activity 中发送消息 20 * 21 * @param SerializableKey 系列化键值 22 * @param obj 消息内容 23 */ 24 public static void ActivityHandlerMsg(final String SerializableKey, final Object obj) { 25 new Thread(new Runnable() { 26 @Override 27 public void run() { 28 /** 29 * myHandler 向CustomActivity中发送消息 30 * MyHandler myHandler = MyHandler.getInstance();这句
*必须放在线程内部,如果放在外面会导致getInstance(),Handler实类为空,Handler线程异常 31 */ 32 MyHandler myHandler = MyHandler.getInstance(); 33 message = new Message(); 34 Bundle bundle = new Bundle(); 35 bundle.putSerializable(SerializableKey, (Serializable) obj); 36 message.setData(bundle); 37 myHandler.sendMessage(message); 38 } 39 }).start(); 40 41 } 42 43 }
下面用服务简单描述发送消息的过程:
1 package dfrz.me.android.pcfileshare.service; 2 3 import android.app.Service; 4 import android.content.Intent; 5 import android.os.Binder; 6 import android.os.IBinder; 7 import android.os.Message; 8 import android.util.Log; 9 10 public class MyService extends Service { 11 12 private MyBinder mybinder = new MyBinder(); 13 // 得到Handler实类 14 MyHandler myHandler = MyHandler.getInstance(); 15 16 public class MyBinder extends Binder { 17 /** 18 * 消息发送函数 19 * @param chatMsgEntity 20 */ 21 public void sendMsg(final ADInfo data) { 22 new Thread(new Runnable() { 23 @Override 24 public void run() { 25 // TODO Auto-generated method stub 26 ADInfo adInfo = new ADInfo(); 27 adInfo.setId("xxxxxx"); 28 adInfo.setUrl("xxxxxxx"); 29 ....... 30 //发送消息到 Activity 31 SendHandlerMsg.ActivityHandlerMsg("ACT",adInfo); 32 } 33 }).start(); 34 } 35 36 /** 37 * 添加其他键值数据 38 * @param data 39 */ 40 public void sendMsg(final ADInfo data) { 41 new Thread(new Runnable() { 42 @Override 43 public void run() { 44 // TODO Auto-generated method stub 45 ADInfo adInfo = new ADInfo(); 46 adInfo.setId("xxxxxx"); 47 adInfo.setUrl("xxxxxxx"); 48 ....... 49 //发送消息到 Activity 50 SendHandlerMsg.ActivityHandlerMsg("ACTIVITY",adInfo); 51 } 52 }).start(); 53 } 54 55 } 56 57 public MyService() { 58 } 59 60 @Override 61 public IBinder onBind(Intent intent) { 62 return mybinder; 63 } 64 65 @Override 66 public void onCreate() { 67 68 } 69 70 }
Activity代码展示:
1 import android.content.ActivityNotFoundException; 2 import android.content.Intent; 3 import android.net.Uri; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.Button; 7 import android.widget.TextView; 8 import android.widget.Toast; 9 10 import dfrz.me.android.pcfileshare.R; 11 import dfrz.me.android.pcfileshare.base.CustomActivity; 12 13 public class MainActivity extends CustomActivity implements View.OnClickListener { 14 private Button sendMsg1, SendMsg2; 15 private TextView showMsg; 16 17 @Override 18 protected void onCreate(Bundle savedInstanceState) { 19 super.onCreate(savedInstanceState); 20 setContentView(R.layout.main_activity); 21 initView(); 22 initData(); 23 initOnClick(); 24 } 25 26 @Override 27 protected void initView() { 28 sendMsg1 = (Button) findViewById(R.id.sendMsg1); 29 sendMsg2 = (Button) findViewById(R.id.sendMsg2); 30 showMsg = (TextView) findViewById(R.id.showMsg); 31 } 32 33 @Override 34 protected void initData() { 35 36 } 37 38 @Override 39 protected void initOnClick() { 40 sendMsg1.setOnClickListener(this); 41 sendMsg2.setOnClickListener(this); 42 back.setOnClickListener(this); 43 } 44 45 @Override 46 public void recvMessageFormHandler(Bundle bundle) { 47 ADInfo adInfo = new ADInfo(); 48 49 adInfo = (ADInfo) bundle.getSerializable("ACTI"); 50 if (adInfo != null) { 51 showMsg.setText(adInfo.getUrl() + ""); 52 } 53 // 这里可新new 一个实例接收消息 54 /** 55 * ChatMsg chatMsg = new ChatMsg(); chatMsg = (ChatMsg) 56 * bundle.getSerializable("CHAT"); 先判断chatMsg非空则接收到消息可更新UI 57 */ 58 Appinfo adInfo1 = new ADInfo(); 59 adInfo1 = (ADInfo) bundle.getSerializable("ACTI"); 60 if (adInfo1 != null) { 61 showMsg.setText(adInfo.getUrl() + ""); 62 } 63 } 64 65 @Override 66 public void onClick(View view) { 67 switch (view.getId()) { 68 case R.id.sendMsg1: 69 { ADInfo adInfo = new ADInfo(); 70 adInfo.setId("xxxxxx"); 71 adInfo.setUrl("xxxxxxx"); 72 ....... 73 binder.sendMsgA(adInfo);} 74 break; 75 case R.id.sendMsg2:{ 76 ADInfo adInfo = new ADInfo(); 77 adInfo.setId("1111111"); 78 adInfo.setUrl("1111111111"); 79 ....... 80 binder.sendMsgB(adInfo);} 81 break; 82 } 83 } 84 85 }
效果怎么样,这就不展示了,仅供参看,如有问题可提出来大家解决,有更好的建议还请各位大神多多指点,毕竟我还新手。thank you!