package com.jay.msgapp2;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
public class BService extends Service {
//记录下客户端发过来的 Messenger
Messenger clientMessenger;
//接受客户端发过来的消息
Messenger messenger = new Messenger(new Handler(Looper.myLooper()) {
@Override
public void handleMessage(Message msg) {
//客户端发送来的数据 msg 中还有齐他参数,客户端发送过来都可以拿到
String clientData = msg.getData().getString("data");
//客户端的 Messenger 对象
clientMessenger = msg.replyTo;
//发送数据返回给客户端
sendMsgToClient();
super.handleMessage(msg);
}
});
//服务端绑定器
@Override
public IBinder onBind(Intent intent) {
//绑定成功
return messenger.getBinder();
}
//发送数据返回给客户端
private void sendMsgToClient(){
Message message = Message.obtain();
Bundle bundle = new Bundle();
bundle.putString("data","成功返回给客户端数据...");
message.setData(bundle);
try {
clientMessenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
服务端AndroidManifest.xml在application节点下,把上面的服务配置一下:<service android:name=".BService" android:enabled="true" android:exported="true"></service>
服务端的MainActivity中启动服务
package com.jay.msgapp2;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent1 = new Intent(this, BService.class);
startService(intent1);
}
}
客户端
package com.jay.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
public TextView mtxtMsg;
public Messenger sendMessenger;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mtxtMsg = findViewById(R.id.txtMsg);
//一个按钮来发消息
Button btnPlay = (Button) findViewById(R.id.btn1);
try {
connectService();//建立连接,构建 sendMessenger
} catch (Exception ex) {
mtxtMsg.setText("连接异常:" + ex.getMessage());
}
btnPlay.setOnClickListener(view -> {
try {
Message message = Message.obtain(null, 1);
//把自己的Messenger带进去 服务端拿到之后 可以直接通过这个对象发数据过来
//就是服务端的 clientMessenger
message.replyTo = replyMessenger;
Bundle bundle = new Bundle();
bundle.putString("data", "服务器你好");//key和服务端的一致
message.setData(bundle);
//发送消息的方法
sendMessenger.send(message);
} catch (RemoteException ex) {
mtxtMsg.setText("远程异常:" + ex.getMessage());
} catch (Exception exception) {
mtxtMsg.setText("发送异常:" + exception.getMessage());
}
});
}
/**
* 和服务器建立连接 连接成功之后 sendMessenger 就是发消息的对象。
**/
private void connectService() throws Exception {
ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
sendMessenger = new Messenger(service);//连接成功
}
@Override
public void onServiceDisconnected(ComponentName name) {
// Log.e("kk", "链接断开!");
}
};
Intent intent = new Intent();
//需要在AndroidManifest.xml中配置包名的可见性com.jay.msgapp2
intent.setComponent(new ComponentName("com.jay.msgapp2", "com.jay.msgapp2.BService"));
boolean res = getApplicationContext().bindService(intent, serviceConnection, BIND_AUTO_CREATE);
if (!res) {
throw new Exception("连接失败");
}
}
//客户端的Messenger
Messenger replyMessenger = new Messenger(new Handler(Looper.myLooper()) {
@Override
public void handleMessage(Message msg) {
String data = msg.getData().getString("data");//服务端返回的数据
mtxtMsg.setText("返回:" + data);
super.handleMessage(msg);
}
});
}
客户端连接服务端的时候调用bindService方法,要加上 getApplicationContext().bindService(intent, serviceConnection, BIND_AUTO_CREATE);
build.gradle中要配置 compileSdk 31 minSdk 31 targetSdk 31,至少30,因为我的手机是Android12,所以我配置的是31。AndroidManifest.xml中配置<application tools:targetApi="31"...
客户端的AndroidManifest.xml中配置包可见性,或者配置权限可发现所有包<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<queries>
<package android:name="com.jay.msgapp2" />
</queries>
总的来说和网上大部分文章差不多,只是很多文章没有写 服务端的版本配置,启动服务。客户端的软件包可见性配置,连接服务使用getApplicationContext().bindService()
另外,gradle插件的版本也不能太低,具体是多少我也没试,看别人说不能太低,我的 Android Gradle Plugin Version 7.3.0 / Gradle Version 7.4。
参考文章:
https://blog.csdn.net/qq379454816/article/details/52573476
https://www.jb51.net/article/76470.htm
https://www.jb51.net/article/76474.htm
https://www.jianshu.com/p/b2c86d4aa366
软件包可见性 https://blog.csdn.net/yang_study_first/article/details/119787421
浙公网安备 33010602011771号