无法让我的 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;
}