无法让我的 Android 绑定服务与我的网络侦听器代码一起工作
Cannot get my Android bound service to work with my network listener code
我正在处理的 Android 应用程序与“服务器”通信 运行ning 在与我的应用程序相同的设备上。
因为我需要不断地监听这个服务器,所以我决定把它作为一个绑定服务。我看了官方Android文档here and a good example here.
当我 运行 在我的开发平板电脑上使用这两个示例时,它们都运行良好。但是,当我尝试将示例合并到我自己的应用程序中时,它似乎不起作用。
这是我的MainActivity.java:
public class MainActivity extends AppCompatActivity {
Listener myListener;
boolean isBound = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(this, Listener.class);
startService(intent);
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
myListener.listenToServer();
Toast.makeText(this, Integer.toString(myListener.getPort()), Toast.LENGTH_LONG).show();
}
@Override
protected void onStop() {
super.onStop();
if(isBound){
unbindService(serviceConnection);
isBound = false;
}
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Listener.LocalBinder localBinder = (Listener.LocalBinder) service;
myListener = localBinder.getService();
isBound = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
isBound = false;
}
};
}
这是我要绑定的服务,Listener.java:
public class Listener extends Service {
private boolean keepWorking = true;
private int localPort;
private final IBinder iBinder = new LocalBinder();
public class LocalBinder extends Binder {
Listener getService(){
return Listener.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return iBinder;
}
public void listenToServer(){
try {
byte[] buffer = new byte[16 * 1024];
DatagramPacket recvPacket = new DatagramPacket(buffer, buffer.length);
DatagramSocket server = new DatagramSocket(0);
server.setSoTimeout(1000);
localPort = server.getLocalPort();
while (keepWorking) {
try {
server.receive(recvPacket);
byte[] data = new byte[recvPacket.getLength()];
System.arraycopy(recvPacket.getData(), 0, data, 0, data.length);
} catch ( IOException ioe) {
// something here
}
}
} catch (SocketException se) {
// something here
}
}
public int getPort() {
return this.localPort;
}
public void stopWorking() {
this.keepWorking = false;
}
}
每当我尝试 运行 我的应用程序时,我都会收到以下错误:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'Listener.listenToServer()' on a null object reference
at MainActivity.onStart(MainActivity.java:19)
myListener.listenToServer();
.
行
我知道我可以使用线程让它工作(因为我已经做到了),但这需要一种不太优雅的方法。我喜欢绑定服务路由,因为我可以轻松地在我的应用程序 UI.
中使用来自服务器的数据
所以,这是怎么回事?我做错了什么?
谢谢
问题是 onServiceConnected()
回调不会被同步调用。您只是要求系统为您绑定服务,这不会发生 immediately/synchronously。一旦绑定发生,您就会收到 onServiceConnected()
回调通知。因此在 bindService(...)
行之后你的 myListener
还没有被初始化。
在 onServiceConnected()
回调中执行 myListener.listenToServer()
:
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Listener.LocalBinder localBinder = (Listener.LocalBinder) service;
myListener = localBinder.getService();
myListener.listenToServer();
isBound = true;
}
我正在处理的 Android 应用程序与“服务器”通信 运行ning 在与我的应用程序相同的设备上。
因为我需要不断地监听这个服务器,所以我决定把它作为一个绑定服务。我看了官方Android文档here and a good example here.
当我 运行 在我的开发平板电脑上使用这两个示例时,它们都运行良好。但是,当我尝试将示例合并到我自己的应用程序中时,它似乎不起作用。
这是我的MainActivity.java:
public class MainActivity extends AppCompatActivity {
Listener myListener;
boolean isBound = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(this, Listener.class);
startService(intent);
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
myListener.listenToServer();
Toast.makeText(this, Integer.toString(myListener.getPort()), Toast.LENGTH_LONG).show();
}
@Override
protected void onStop() {
super.onStop();
if(isBound){
unbindService(serviceConnection);
isBound = false;
}
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Listener.LocalBinder localBinder = (Listener.LocalBinder) service;
myListener = localBinder.getService();
isBound = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
isBound = false;
}
};
}
这是我要绑定的服务,Listener.java:
public class Listener extends Service {
private boolean keepWorking = true;
private int localPort;
private final IBinder iBinder = new LocalBinder();
public class LocalBinder extends Binder {
Listener getService(){
return Listener.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return iBinder;
}
public void listenToServer(){
try {
byte[] buffer = new byte[16 * 1024];
DatagramPacket recvPacket = new DatagramPacket(buffer, buffer.length);
DatagramSocket server = new DatagramSocket(0);
server.setSoTimeout(1000);
localPort = server.getLocalPort();
while (keepWorking) {
try {
server.receive(recvPacket);
byte[] data = new byte[recvPacket.getLength()];
System.arraycopy(recvPacket.getData(), 0, data, 0, data.length);
} catch ( IOException ioe) {
// something here
}
}
} catch (SocketException se) {
// something here
}
}
public int getPort() {
return this.localPort;
}
public void stopWorking() {
this.keepWorking = false;
}
}
每当我尝试 运行 我的应用程序时,我都会收到以下错误:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'Listener.listenToServer()' on a null object reference
at MainActivity.onStart(MainActivity.java:19)
myListener.listenToServer();
.
我知道我可以使用线程让它工作(因为我已经做到了),但这需要一种不太优雅的方法。我喜欢绑定服务路由,因为我可以轻松地在我的应用程序 UI.
中使用来自服务器的数据所以,这是怎么回事?我做错了什么?
谢谢
问题是 onServiceConnected()
回调不会被同步调用。您只是要求系统为您绑定服务,这不会发生 immediately/synchronously。一旦绑定发生,您就会收到 onServiceConnected()
回调通知。因此在 bindService(...)
行之后你的 myListener
还没有被初始化。
在 onServiceConnected()
回调中执行 myListener.listenToServer()
:
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Listener.LocalBinder localBinder = (Listener.LocalBinder) service;
myListener = localBinder.getService();
myListener.listenToServer();
isBound = true;
}