Android为TV端助力 不需要Socket的跨进程推送消息AIDL!
上篇介绍了跨进程实时通讯http://www.cnblogs.com/xiaoxiaing/p/5818161.html
但是他有个缺点就是服务端无法推送消息给客户端,今天这篇文章主要说的就是服务器推送数据给客户端
原理:客户端注册回调函数,并把回调的对象当做参数传递给服务端,这种服务端调用函数其实就是回调客户端的函数,废话不多说,直接看代码!
首先是服务端的AIDL文件
IAidlHguConnCallback.aidl文件
package tel.gateway.connservice;
interface IAidlHguConnCallback{
void update( String ssid, String pwd);
}
IAidlHguConnCallback.aidl文件
package tel.gateway.connservice;
import tel.gateway.connservice.IAidlHguConnCallback;
interface IAidlHguConnService{
void setListener(IAidlHguConnCallback listener);
void unregisterListener(IAidlHguConnCallback listener);
void setWifiInfo(String username, String pwd, String security);
void getWifiInfo();
}
注意客户端那边直接把服务端的包直接复制过去就可以的,因为aidl文件要保证两边的包名类名是完全一样的
接下来就是服务端的代码:
public class MyService extends Service{
protected static final String TAG = "MyService";
private String ssid;
private String mPwd;
/**
* 我们知道AIDL方法是在服务端的Binder线程池中执行的,当我们多个客户端访问服务端的时候,容易发生并发现象,
* 这里采用CopyOnWriteArrayList,这个CopyOnWriteArrayList支持并发读/写,而我们这里直接使用
* CopyOnWriteArrayList来进行自动的线程同步
*/
//private CopyOnWriteArrayList<IAidlHguConnCallback> callbacks = new CopyOnWriteArrayList<IAidlHguConnCallback>();
private RemoteCallbackList<IAidlHguConnCallback> callbacks = new RemoteCallbackList<IAidlHguConnCallback>();
private AtomicBoolean atomicBoolean = new AtomicBoolean(false);
private int i =0;//用来判断是否循环发生SSID
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return binder;
}
@Override
public void onCreate() {
super.onCreate();
//在这里开启一个线程,每隔5S向所有用户推送wifi的SSID和PWD
new Thread(new Runnable() {
@Override
public void run() {
while (!atomicBoolean.get()) {
try {
Thread.sleep(5000);
//这里就是向客户端推送的消息,你想发什么消息依照自己的项目来,我这里只是示范!
if(ssid!=null&&mPwd!=null){
OnSendSsidAndPwd(ssid+i, mPwd+i);
i++;
}
} catch (Exception e) {
}
}
}
}).start();
}
private void OnSendSsidAndPwd(String ssid,String pwd) throws RemoteException{
for(int i =0;i<callbacks.beginBroadcast();i++){
IAidlHguConnCallback l = callbacks.getBroadcastItem(i);
if(l !=null){
l.update(ssid, pwd);
}
}
callbacks.finishBroadcast();
}
private Binder binder = new IAidlHguConnService.Stub() {
@Override
public void unregisterListener(IAidlHguConnCallback listener)
throws RemoteException {
callbacks.unregister(listener);
}
@Override
public void setWifiInfo(String username, String pwd, String security)
throws RemoteException {
//TODO
//这里处理客户端用户传递过来的wifi名字和密码
//比如我把传递过来的数值实例化给成员变量,然后在getWifiInfo传递给客户端
ssid = username;
mPwd = pwd;
}
@Override
public void setListener(IAidlHguConnCallback listener)
throws RemoteException {
//这里把所有注册过监听的客户端收集起来,以便接下来可以传递数据给他们
callbacks.register(listener);
}
@Override
public void getWifiInfo() throws RemoteException {
Log.i(TAG, "收到!!!");
OnSendSsidAndPwd(ssid, mPwd);//通知所有注册过监听的用户,告诉他们密码和用户名
}
};
}
客户端的代码:
public class Client extends Service{
private static final String TAG = "Client";
public Handler handler = new Handler(){
public void handleMessage(Message msg) {
String ssid = msg.getData().getString("ssid");
String pwd = msg.getData().getString("pwd");
Log.i("client --- TAG", "msg:;"+ssid+"pwd:"+pwd);
};
};
protected IAidlHguConnService mService;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Intent mIntent = new Intent();
mIntent.setClassName("com.example.test1", "com.example.test1.MyService");
bindService(mIntent, mBindService, Context.BIND_AUTO_CREATE);
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
//当服务被销毁时记得销毁绑定的监听和service
unbindService(mBindService);
try {
mService.unregisterListener(stub);
} catch (RemoteException e) {
e.printStackTrace();
}
}
/**
* 注意此回调方法是在客户端的Binder线程池中执行的,因为威力便于更新UI,我们需要创建一个handler
*/
private IAidlHguConnCallback.Stub stub = new IAidlHguConnCallback.Stub() {
@Override
public void update(String ssid, String pwd) throws RemoteException {
Message message = new Message();
Bundle bundle = new Bundle();
bundle.putString("ssid", ssid);
bundle.putString("pwd", pwd);
message.setData(bundle);
handler.sendMessage(message);
}
};
private ServiceConnection mBindService = new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = IAidlHguConnService.Stub.asInterface(service);
try {
mService.setListener(stub);//设置回调函数
mService.setWifiInfo("想偷WIFI?", "123456", "0");
mService.getWifiInfo();
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
};
}
还有一点需要注意,当客户端连接服务端的时候你要保证服务端的service是开启了,然后记得在清单文件里面注册service
<service
android:name="com.example.test1.MyService"
android:enabled="true"
android:exported="true" >
</service>
如果还发现什么错误可以自行看LOGCAT,比如权限没加什么的!
Android为TV端助力 不需要Socket的跨进程推送消息AIDL!的更多相关文章
- android不需要Socket的跨进程推送消息AIDL!
上篇介绍了跨进程实时通讯http://www.cnblogs.com/xiaoxiaing/p/5818161.html 但是他有个缺点就是服务端无法推送消息给客户端,今天这篇文章主要说的就是服务器推 ...
- Android为TV端助力 史上最简单易懂的跨进程通讯(Messenger)!
不需要AIDL也不需要复杂的ContentProvider,也不需要SharedPreferences或者共享存储文件! 只需要简单易懂的Messenger,它也称为信使,通过它可以在不同进程中传递m ...
- 用JPUSH极光推送实现服务端向安装了APP应用的手机推送消息(C#服务端接口)
这次公司要我们做一个功能,就是当用户成功注册以后,他登录以后要收到消息,当然这个消息是安装了我们的手机APP应用的手机咯. 极光推送的网站的网址是:https://www.jpush.cn/ 极光推送 ...
- Android为TV端助力 UDP协议
废话不多说.直接上代码! 一. 接收端 1.创建UDP连接 public void init() { try { //开关的作用 isRunning = true; DatagramSocket mU ...
- Android IPC机制(五)用Socket实现跨进程聊天程序
1.Socket简介 Socket也称作“套接字“,是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信.它分为流式套接字和数据包套接 ...
- Android为TV端助力 转载:RecyclerView分页加载
package com.android.ryane.pulltoloaddata_recyclerview; import android.os.Handler;import android.os.L ...
- Android为TV端助力(转载)
作者地址http://www.jianshu.com/u/63915ef020e2 针对Android Tv的自定义RecyclerView 作者 wenju_song 关注 2016.12.09 1 ...
- Android为TV端助力之Webview与JS双向交互
package com.hhzt.iptv.adservice; import android.app.Activity;import android.graphics.Bitmap;import a ...
- Android为TV端助力之WebView开发踩坑一
在Android清单配置文件里面 自定义application时,在4.4系统上面不能加上一个属性,见下图 否则界面将不会显示任何数据,在更高或者更低的系统上面没有测试!
随机推荐
- deque源码3(deque的构造与内存、ctor、push_back、push_front)
deque源码1(deque概述.deque中的控制器) deque源码2(deque迭代器.deque的数据结构) deque源码3(deque的构造与内存.ctor.push_back.push_ ...
- 如何在mpvue下收集小程序的formId
什么是formId formId是小程序可以向用户发送模板消息的通行证,简单而言,你只有获取到formId,把它交给后台,后台同学才能向用户发送通知消息,而这个通行证的有效期只有七天.这是微信为了防止 ...
- Spring IOC分析
前言 关于Spring,我想无需做太多的解释了.每个Java程序猿应该都使用过他.Spring的ioc和aop极大的方便了我们的开发,但是Spring又有着不好的一面,为了符合开闭原则,Spring的 ...
- struts2整合uploadify插件怎样传参数
关于uploadify3.1,先看下帮助文档中的有些知识. 其中有个onUploadStart方法,我们可以使用这个向后台传参. 下面举个例子, js: <script type="t ...
- 线程池ThreadPool及Task调度死锁分析
近1年,偶尔发生应用系统启动时某些操作超时的问题,特别在使用4核心Surface以后.笔记本和台式机比较少遇到,服务器则基本上没有遇到过. 这些年,我写的应用都有一个习惯,就是启动时异步做很多准备工作 ...
- 非业务 Oracle SQL 语句备份
1.创建一个将 Oracle 生成的 GUID 格式化为标准的 GUID 的函数 2.在 PLSQL 中测试并输出语句异常的语句块 3.在查询语句中日期的一种特殊表示方法 4.利用 ROWNUM 做分 ...
- Python系列:四、Python函数--技术流ken
Python函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也可 ...
- Gitlab仓库搭建及在linux/windows中免密使用gitlab(二)--技术流ken
Gitlab简介 GitLab 是一个用于仓库管理系统的开源项目,使用Git作为代码管理工具,并在此基础上搭建起来的web服务. 可通过Web界面进行访问公开的或者私人项目.它拥有与Github类似的 ...
- HDFS简单测试
使用Hadoop的Java客户端API操作分布式文件系统#获取文件系统实现//hdfs://master01:9000/FileSystem get(URI uri[,Configuration co ...
- 我的python渗透测试工具之主机嗅探
嗅探工具的主要目标是基于UDP发现目标网络中的存活主机,选择UDP的原因是UDP访问过程开销小. 由于很多的操作系统在处理UDP端口的闭合时都会存在一个共性,我们也正是利用这个共性来开展确定此IP上是 ...