上面学习了线程通过Massage发送字符串消息,Handler接收字符串消息,这样的形式来更新ui,接下来,一起分享怎么把一个对象利用消息机制发送出去,让主线程接收来更新ui。
下面就利用一个服务Server,Handler,Activity,和一个对象类分享具体实现情况。
首先创建一个个类,什么都行。例如:
package dfrz.me.android.pcfileshare.bean; import java.io.Serializable; /**
* 描述:广告信息</br>
*/
public class ADInfo implements Serializable{ String id = "";
String url = "";
String content = "";
String type = ""; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getUrl() {
return url;
} public void setUrl(String url) {
this.url = url;
} public String getContent() {
return content;
} public void setContent(String content) {
this.content = content;
} public String getType() {
return type;
} public void setType(String type) {
this.type = type;
} }
ADInfo
创建一个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); }
Activity父类
编写自己的Handle消息接收,和广播到每个活动界面上,前提是每个Activity都要继承父类,并实现接收消息的方法。
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log; import java.util.ArrayList; import dfrz.me.android.pcfileshare.base.CustomActivity; /**
* Created by Administrator on 2016/11/18.
*/
public class MyHandler extends Handler {
private ArrayList<CustomActivity> activityList; private Bundle bundle;
private MyHandler(){
activityList = new ArrayList<CustomActivity>();
} private static MyHandler instance = null; @Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
bundle = msg.getData();
try {
if(activityList.size()>0){
for(CustomActivity customActivity:activityList){
//向每个customActivity内发送消息
customActivity.recvMessageFormHandler(bundle);
}
}
} catch (Exception e) {
// TODO: handle exception
}
} public static MyHandler getInstance(){
if(instance == null){
instance = new MyHandler();
}
return instance;
}
public void registerActivity(CustomActivity activity)
{
Log.d("HANDLER", "add "+activity.toString());
activityList.add(activity);
}
public void unRegisterActivity(CustomActivity activity){
Log.d("clientApp","remove"+activity.toString());
activityList.remove(activity);
}
}
MyHandler
为了方便发送不同的对象消息数据,封装发送消息方法:
import android.os.Bundle;
import android.os.Message; import java.io.Serializable; /**
* Created by Administrator on 2017/1/16.
*/ public class SendHandlerMsg { private static Message message; /**
* 建立bundle 向 fragment 中发送消息
*
* @param SerializableKey 系列化键值
* @param obj 消息内容,传入时必须先系列化对象,不然数据发送不出去,会导致堵塞异常
* 建立bundle 向 Activity 中发送消息
*
* @param SerializableKey 系列化键值
* @param obj 消息内容
*/
public static void ActivityHandlerMsg(final String SerializableKey, final Object obj) {
new Thread(new Runnable() {
@Override
public void run() {
/**
* myHandler 向CustomActivity中发送消息
* MyHandler myHandler = MyHandler.getInstance();这句
*必须放在线程内部,如果放在外面会导致getInstance(),Handler实类为空,Handler线程异常
*/
MyHandler myHandler = MyHandler.getInstance();
message = new Message();
Bundle bundle = new Bundle();
bundle.putSerializable(SerializableKey, (Serializable) obj);
message.setData(bundle);
myHandler.sendMessage(message);
}
}).start(); } }
下面用服务简单描述发送消息的过程:
package dfrz.me.android.pcfileshare.service; import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.Message;
import android.util.Log; public class MyService extends Service { private MyBinder mybinder = new MyBinder();
// 得到Handler实类
MyHandler myHandler = MyHandler.getInstance(); public class MyBinder extends Binder {
/**
* 消息发送函数
* @param chatMsgEntity
*/
public void sendMsg(final ADInfo data) {
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
ADInfo adInfo = new ADInfo();
adInfo.setId("xxxxxx");
adInfo.setUrl("xxxxxxx");
.......
//发送消息到 Activity
SendHandlerMsg.ActivityHandlerMsg("ACT",adInfo);
}
}).start();
} /**
* 添加其他键值数据
* @param data
*/
public void sendMsg(final ADInfo data) {
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
ADInfo adInfo = new ADInfo();
adInfo.setId("xxxxxx");
adInfo.setUrl("xxxxxxx");
.......
//发送消息到 Activity
SendHandlerMsg.ActivityHandlerMsg("ACTIVITY",adInfo);
}
}).start();
} } public MyService() {
} @Override
public IBinder onBind(Intent intent) {
return mybinder;
} @Override
public void onCreate() { } }
Server
Activity代码展示:
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast; import dfrz.me.android.pcfileshare.R;
import dfrz.me.android.pcfileshare.base.CustomActivity; public class MainActivity extends CustomActivity implements View.OnClickListener {
private Button sendMsg1, SendMsg2;
private TextView showMsg; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
initView();
initData();
initOnClick();
} @Override
protected void initView() {
sendMsg1 = (Button) findViewById(R.id.sendMsg1);
sendMsg2 = (Button) findViewById(R.id.sendMsg2);
showMsg = (TextView) findViewById(R.id.showMsg);
} @Override
protected void initData() { } @Override
protected void initOnClick() {
sendMsg1.setOnClickListener(this);
sendMsg2.setOnClickListener(this);
back.setOnClickListener(this);
} @Override
public void recvMessageFormHandler(Bundle bundle) {
ADInfo adInfo = new ADInfo(); adInfo = (ADInfo) bundle.getSerializable("ACTI");
if (adInfo != null) {
showMsg.setText(adInfo.getUrl() + "");
}
// 这里可新new 一个实例接收消息
/**
* ChatMsg chatMsg = new ChatMsg(); chatMsg = (ChatMsg)
* bundle.getSerializable("CHAT"); 先判断chatMsg非空则接收到消息可更新UI
*/
Appinfo adInfo1 = new ADInfo();
adInfo1 = (ADInfo) bundle.getSerializable("ACTI");
if (adInfo1 != null) {
showMsg.setText(adInfo.getUrl() + "");
}
} @Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.sendMsg1:
{ ADInfo adInfo = new ADInfo();
adInfo.setId("xxxxxx");
adInfo.setUrl("xxxxxxx");
.......
binder.sendMsgA(adInfo);}
break;
case R.id.sendMsg2:{
ADInfo adInfo = new ADInfo();
adInfo.setId("1111111");
adInfo.setUrl("1111111111");
.......
binder.sendMsgB(adInfo);}
break;
}
} }
效果怎么样,这就不展示了,仅供参看,如有问题可提出来大家解决,有更好的建议还请各位大神多多指点,毕竟我还新手。thank you!