当从主线程调用而不是按钮事件时,对服务的 IPC 调用会导致 NullPointerException

IPC call to service causes NullPointerException when called from main thread but not on button event

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

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

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

我的 MainActivicty

       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>

发生这种情况是因为 iMyAidlInterface 在您的 onCreate 通话中是 null。在您的连接侦听器通过 onServiceConnected 给您回电之前,它不会被设置。绑定是一个异步操作。