无法让我的Android绑定服务与我的网络侦听器代码一起使用

时间:2017-05-03 16:32:52

标签: android android-service-binding

我正在处理的Android应用程序,与"服务器"在与我的应用程序相同的设备上运行。

由于我需要不断收听此服务器,因此我决定将其作为绑定服务。我查看了官方Android文档 here 以及一个很好的示例 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;
    }
}

每当我尝试运行我的应用时,都会收到以下错误:

  

引起:java.lang.NullPointerException:尝试调用虚方法' Listener.listenToServer()'在空对象引用上

     

在MainActivity.onStart(MainActivity.java:19)

哪一行是myListener.listenToServer();

我知道我可以使用线程来实现这一点(因为我已经完成了它),但这需要一种不那么优雅的方法。我喜欢绑定的服务路线,因为我可以在我的应用程序的UI中轻松使用来自服务器的数据。

那么,发生了什么?我做错了什么?

由于

1 个答案:

答案 0 :(得分:1)

问题是onServiceConnected()回调不会同步调用。您只是要求系统为您绑定服务,这不会立即/同步发生。一旦发生绑定,您将收到onServiceConnected()回调通知。因此,在bindService(...)行之后,您的myListener尚未初始化。

myListener.listenToServer()回调中执行onServiceConnected()

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
    Listener.LocalBinder localBinder = (Listener.LocalBinder) service;
    myListener = localBinder.getService();
    myListener.listenToServer();
    isBound = true;
}