Java IPC对服务的调用在从主线程调用时导致NullPointerException,但不是在按钮事件上

Java IPC对服务的调用在从主线程调用时导致NullPointerException,但不是在按钮事件上,java,android,ipc,aidl,Java,Android,Ipc,Aidl,我正在尝试使用.aidl文件中定义的IPC连接创建服务 服务启动,服务连接可以绑定到它,但当从同一线程调用IPC API时,会导致NullPointerException。 当对IPC API的调用被放入一个按钮上的事件中时,按下该按钮即可工作 如何解决这个问题,以便在没有按钮事件启动的情况下完成呼叫 我的主要活动 public class MainActivity extends AppCompatActivity { public final String T

我正在尝试使用.aidl文件中定义的IPC连接创建服务

服务启动,服务连接可以绑定到它,但当从同一线程调用IPC API时,会导致
NullPointerException
。 当对IPC API的调用被放入一个按钮上的事件中时,按下该按钮即可工作

如何解决这个问题,以便在没有按钮事件启动的情况下完成呼叫

我的主要活动

       public class MainActivity extends AppCompatActivity {

        public final String TAG = "Main Activity";
        IMyAidlInterface iMyAidlInterface;
        private ServiceConnection mConnection = new ServiceConnection() {
            public void onServiceConnected(ComponentName className, IBinder service) {
                iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
            }

            public void onServiceDisconnected(ComponentName className) {
                iMyAidlInterface = null;
            }
        };


        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            Intent interFaceServiceIntent = new Intent(this, IMyAidlService.class);
            bindService(interFaceServiceIntent, mConnection, Context.BIND_AUTO_CREATE);

            Intent sigGenIntent = new Intent(this, signalGenerator.class);
            startService(sigGenIntent);

            Button b = findViewById(R.id.button);

/*
* The following block is what I want to be able to execute. Currently it causes * a NullPointerException 
* Caused by: java.lang.NullPointerException: Attempt to invoke interface method * 'int com.aidltest.IMyAidlInterface.getPid()' on a null object reference
*/
            try {
                iMyAidlInterface.getPid();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
/*
*  The block below using the same interface from within a button event works
*   without problem.
*/

            b.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    try {
                        iMyAidlInterface.getPid();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
参考我的Aidl:

package com.aidltest;
interface IMyAidlInterface {
    int getPid();
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
}
还有我的舱单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.aidltest">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <service
            android:name=".IMyAidlService"
            android:enabled="true"
            android:exported="true">
        </service>
    </application>

</manifest>


发生这种情况是因为在
onCreate
调用中,
iMyAidlInterface
null
。直到您的连接侦听器通过
onServiceConnected
回叫您时,才会设置它。绑定是一种异步操作。

应该/可以如何解决这个问题?我通过添加` while(iMyAidlInterface==null){Log.d(TAG,“Waiting for connection.”);}'所做的缓慢解决方案只会产生一个无限循环。因此,从这一点来看,它似乎是在同一个线程中完成的。我假设我要做的是等待服务启动。但是将Thread.sleep或check循环放在主线程中似乎并不能解决问题。它是异步的,所以您需要使代码成为事件驱动的。在执行
onServiceConnected
之前,您无法调用该服务。您可以让它向
处理程序发送消息或
Runnable
,或类似的内容。在主线程上调用服务时要小心,它们会阻塞调用,如果服务调用时间过长,可能会导致ANR。