im采用的是Mars框架,这一篇是关于发送消息模块。该文是建立在上一篇关于Mars搭建的基础上。也就是说当前默认你的mars环境已经搭建完成。
第一步:在Application初始化Mars项目
//APP的属性类 包括账号类和设备类 public static AppLogic.AccountInfo accountInfo = new AppLogic.AccountInfo( new Random(System.currentTimeMillis() / 1000).nextInt(), "anonymous");
//启动mars服务 MarsServiceNative.setProfileFactory(new MarsServiceProfileFactory() { @Override public MarsServiceProfile createMarsServiceProfile() { return new DebugMarsServiceProfile(){ @Override public String longLinkHost() { return "marsopen.cn"; } }; } }); //初始化mars服务 MarsServiceProxy.init(this, getMainLooper(), null); //mars账号设置 MarsServiceProxy.inst.accountInfo = accountInfo;
/**
* Created by malei on 2018/4/16.
*/
public class MyApplication extends Application {
private static final String TAG = "Mars.SampleApplication";
private static Context context;
//APP的属性类 包括账号类和设备类
public static AppLogic.AccountInfo accountInfo = new AppLogic.AccountInfo(
new Random(System.currentTimeMillis() / 1000).nextInt(), "anonymous");
public static volatile boolean hasSetUserName = false;
@Override
public void onCreate() {
super.onCreate();
context = this;
System.loadLibrary("stlport_shared");
System.loadLibrary("marsxlog");
openXlog();
//启动mars服务
MarsServiceNative.setProfileFactory(new MarsServiceProfileFactory() {
@Override
public MarsServiceProfile createMarsServiceProfile() {
return new DebugMarsServiceProfile(){
@Override
public String longLinkHost() {
return "marsopen.cn";
}
};
}
});
//初始化mars服务
MarsServiceProxy.init(this, getMainLooper(), null);
//mars账号设置
MarsServiceProxy.inst.accountInfo = accountInfo;
// Auto bind all activity event
ActivityEvent.bind(getApplicationContext());
Log.i(TAG, "application started");
CustomActivityOnCrash.install(this);
}
@Override
public void onTerminate() {
Log.i(TAG, "application terminated");
super.onTerminate();
Log.appenderClose();
}
public static void openXlog() {
int pid = android.os.Process.myPid();
String processName = null;
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningAppProcessInfo appProcess : am.getRunningAppProcesses()) {
if (appProcess.pid == pid) {
processName = appProcess.processName;
break;
}
}
if (processName == null) {
return;
}
final String SDCARD = Environment.getExternalStorageDirectory().getAbsolutePath();
final String logPath = SDCARD + "/marssample/log";
String logFileName = processName.indexOf(":") == -1 ? "MarsSample" : ("MarsSample_" + processName.substring(processName.indexOf(":") + 1));
if (BuildConfig.DEBUG) {
Xlog.appenderOpen(Xlog.LEVEL_VERBOSE, Xlog.AppednerModeAsync, "", logPath, logFileName, "");
Xlog.setConsoleLogOpen(true);
} else {
Xlog.appenderOpen(Xlog.LEVEL_INFO, Xlog.AppednerModeAsync, "", logPath, logFileName, "");
Xlog.setConsoleLogOpen(false);
}
Log.setLogImp(new Xlog());
}
public static Context getContext() {
return context;
}
第二步:创建聊天界面ChatActivity.class(我们先做发消息处理)
发送消息使用的工具类是:MarsServiceProxy,方法是send()。send()方法传人的参数是MarsTaskWrapper接口,所以我们需要实现该接口。
- onPreEncode () : 发送之前的拦截
- onPostDecode(): 发送完成后的回调,消息已经到达对方
- onTaskEnd() : 发送完成后的回调,消息已经到达对方
TextMessageTask类为MarsTaskWrapper接口的实现。
/** * Created by malei on 2018/4/17. * 处理发送的消息 */ @TaskProperty( host = "marsopen.cn", path = "/mars/sendmessage", cmdID = Main.CMD_ID_SEND_MESSAGE, longChannelSupport = true, shortChannelSupport = false ) public class TextMessageTask extends NanoMarsTaskWrapper<Chat.SendMessageRequest, Chat.SendMessageResponse> { private Runnable mOnOk; private Runnable mOnError; private Runnable mCallback; private Handler uiHandler = new Handler(Looper.getMainLooper()); //创建主线程的handler /** * * @param topicName : 聊天的频道,两个人聊天的时候,要保证topicName 一致 * @param text */ public TextMessageTask(String topicName, String text) { super(new Chat.SendMessageRequest(), new Chat.SendMessageResponse()); request.accessToken = "test_token"; request.from = MyApplication.accountInfo.userName; request.to = "all"; request.text = text; request.topic = topicName; } /** * 发送之前的拦截 * @param request */ @Override public void onPreEncode(Chat.SendMessageRequest request) { Log.i("TAG",request.text); } /** * 发送完成后的回调 * @param response */ @Override public void onPostDecode(Chat.SendMessageResponse response) { if (response.errCode == Chat.SendMessageResponse.ERR_OK) { mCallback = mOnOk; } else { mCallback = mOnError; } } /** * 发送完成后的回调,消息已经发送给对方了 * @param errType * @param errCode */ @Override public void onTaskEnd(int errType, int errCode) { if (mCallback == null) { mCallback = mOnError; } uiHandler.post(mCallback); } public TextMessageTask onOk(Runnable onOk){ this.mOnOk = onOk; return this; } public TextMessageTask onError(Runnable onError){ this.mOnError = onError; return this; } }
要完成这个类的所有功能还需要,mars给我们提供的两个类Main.class和Chat.class。这两个类直接从demo中就可以获取,这里就不提供了。
第二部分:接收消息的监听
第一步:首先我们需要初始化接收消息的类
private void initMarsPullChat() { //接收新消息的时候使用 final MainService mainService = new MainService(); MarsServiceProxy.setOnPushMessageListener(BaseConstants.CGIHISTORY_CMDID, mainService); MarsServiceProxy.setOnPushMessageListener(BaseConstants.CONNSTATUS_CMDID, mainService); MarsServiceProxy.setOnPushMessageListener(BaseConstants.FLOW_CMDID, mainService); MarsServiceProxy.setOnPushMessageListener(BaseConstants.PUSHMSG_CMDID, mainService); MarsServiceProxy.setOnPushMessageListener(BaseConstants.SDTRESULT_CMDID, mainService); }
/**
* Created by caoshaokun on 16/12/20.
*/
public class MainService implements PushMessageHandler {
public static String TAG = "Mars.Sample.MainService";
private Thread recvThread;
private LinkedBlockingQueue<PushMessage> pushMessages = new LinkedBlockingQueue<>();
private BusinessHandler[] handlers = new BusinessHandler[] {
new MessageHandler(),
new StatisticHandler()
};
public MainService() {
this.start();
}
public void start() {
if (recvThread == null) {
recvThread = new Thread(pushReceiver, "PUSH-RECEIVER");
recvThread.start();
}
}
private final Runnable pushReceiver = new Runnable() {
@Override
public void run() {
while (true) {
try {
PushMessage pushMessage = pushMessages.take();
if (pushMessage != null) {
for (BusinessHandler handler : handlers) {
if (handler.handleRecvMessage(pushMessage)) {
break;
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
try {
Thread.sleep(500);
} catch (InterruptedException e1) {
//
}
}
}
}
};
@Override
public void process(PushMessage message) {
pushMessages.offer(message);
}
}
第二步:创建ChatDataCore类,作为消息的接收者。接收消息是通过广播获取,然后通过观察者模式,通知给被观察者ui界面
/** * Created by malei on 2018/4/23. * 接收消息监听者类 */ public class ChatDataCore extends Observable { private BroadcastReceiver receiver = new RecvMessageReceiver(); private static ChatDataCore inst = new ChatDataCore(); public ChatDataCore() { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(Constants.PUSHACTION); MyApplication.getContext().registerReceiver(receiver, intentFilter); } public static ChatDataCore getInstance() { return inst; } /** * 发送消息和接收消息,都会触发该广播 */ private class RecvMessageReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { if (intent != null && intent.getAction().equals(Constants.PUSHACTION)){ String topic = intent.getStringExtra("msgtopic"); String from = intent.getStringExtra("msgfrom"); String text = intent.getStringExtra("msgcontent"); ChatActivity.recMsg = text; //这两个方法是通知观察者类,数据已经修改 setChanged(); notifyObservers(); } } } }
该类继承了Observable,也就成了被观察者。
第三步:让我们的ChatActivity成为接收消息的观察者,通过继承Observer。
/** * Created by malei on 2018/4/16. * 观察者模式设计 */ public class ChatActivity extends Activity implements Observer { private TextView textView; private EditText editText; private Button btnSend; private String mTopicName = "0" ; //聊天频道 public static String recMsg = ""; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_chat); //接收消息的监听 成为观察者 ChatDataCore.getInstance().addObserver(this); textView = (TextView)this.findViewById(R.id.textView); editText = (EditText)this.findViewById(R.id.editText); btnSend = (Button)this.findViewById(R.id.btn); btnSend.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { onClickBtnSend(); } }); } private void onClickBtnSend() { MyApplication.accountInfo.userName = "malei"; MarsServiceProxy.send(new TextMessageTask("0",editText.getText().toString()) .onOk(new Runnable() { @Override public void run() { Log.i("TAG","onOk"); } }).onError(new Runnable() { @Override public void run() { Log.i("TAG","onError"); } })); } @Override public void update(Observable o, Object arg) { textView.setText(recMsg); } }这样,一个最简单的im项目就搭建完成了!