使用AIDL绑定到后台服务时从不调用OnServiceConnected

时间:2015-03-04 13:44:05

标签: android service aidl

我有一个后台服务,它是在带有广播接收器的BOOT COMPLETE上启动的。

我想要做的是创建另一个使用AIDL接口绑定到该服务的应用程序。

应用程序只是要求用户输入ip号和端口,当他点击按钮时,服务应该接收这些数据。 我的问题是,当我输入数据并单击“提交”时,应用程序崩溃并返回nullPointerException。当我调试应用程序时,我发现根本没有调用OnServiceConnected。

我认为我很好地定义了AIDL文件,我无法弄清楚这里有什么问题。

AIDL文件(aidl在服务和客户端的相同包名内):

interface ISetIpPort{
    void getIpPort(String ip,int port);
}

我的服务(相关方法):

@Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return (new IpPortBinder(getApplicationContext()));
    }

    private static class IpPortBinder extends ISetIpPort.Stub{
        Context context;
        public IpPortBinder(Context context) {
            this.context=context;
        }

        @Override
        public void getIpPort(String ip, int port) throws RemoteException {
            Toast.makeText(context, "Received ip " +ip+" And port "+port, Toast.LENGTH_LONG);

        }

    }

我的申请:

public class MainActivity extends Activity implements OnClickListener,ServiceConnection {
    private Button submitButton,cancelButton;
    private EditText ipText,portText;
    private ISetIpPort binding=null;
    String ip;
    String port;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
        submitButton=(Button) findViewById(R.id.okButton);
        submitButton.setOnClickListener(this);
        cancelButton=(Button) findViewById(R.id.cancelButton);
        cancelButton.setOnClickListener(this);
        ipText=(EditText) findViewById(R.id.ip);
        portText=(EditText) findViewById(R.id.port);
    }

    @Override
    public void onClick(View v) {

        if(v==findViewById(R.id.okButton)){
            ip=ipText.getText().toString();
            port=portText.getText().toString();
            int portInteger=Integer.parseInt(port);
            try {
                binding.getIpPort(ip, portInteger);
            } catch (RemoteException e) {
                // TODO Auto-generated catch block
                Log.e(getClass().getSimpleName(),"Exception requesting to set ip and port",e);
                Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
            }
        }

        if(v==findViewById(R.id.cancelButton)){
            finish();
            System.exit(0);
        }
    }

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        Intent implicit=new Intent(ISetIpPort.class.getName());
        List<ResolveInfo> matches=getPackageManager().queryIntentServices(implicit, 0);
        if(matches.size()==0){
            Toast.makeText(getApplicationContext(), "Cannot find a matching service!", Toast.LENGTH_LONG).show();
        }
        else if (matches.size()>1){
            Toast.makeText(getApplicationContext(), "Found multiple matching services!", Toast.LENGTH_LONG).show();
        }
        else{
            Toast.makeText(getApplicationContext(), "service attached!", Toast.LENGTH_LONG).show();
            Intent explicit=new Intent(implicit);
            ServiceInfo svcInfo=matches.get(0).serviceInfo;
            ComponentName cn=new ComponentName(svcInfo.applicationInfo.packageName, svcInfo.name);
            explicit.setComponent(cn);
            bindService(explicit, this, Context.BIND_WAIVE_PRIORITY);
        }
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        binding=ISetIpPort.Stub.asInterface(service);
        submitButton.setEnabled(true);

    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        binding=null;
        submitButton.setEnabled(false);

    }

}

不要担心我没有验证ip或端口插入。我只是想先测试一下这个IPC。

1 个答案:

答案 0 :(得分:0)

好我的问题在这里:

bindService(explicit, this, Context.BIND_WAIVE_PRIORITY);

应该是

bindService(explicit, this, Context.BIND_AUTO_CREATE);