SyncAdapter- onPerformSync无法访问Internet

And*_*ldo 8 java android android-networking android-syncadapter

我有一个SyncAdapter类连接到MQTT代理并发布服务器的有效负载以接收有效负载.但是,似乎即使onPerformSync()调用该方法,也不存在互联网访问.我以为使用SyncAdapter保证上网?

这是SyncAdapter类

public class SyncAdapter extends AbstractThreadedSyncAdapter {
    private static final String TAG = SyncAdapter.class.getSimpleName();
    private MqttHelper mqttHelper;

    public SyncAdapter(Context context, boolean autoInitialize) {
        super(context, autoInitialize);
        mqttHelper = new MqttHelper(getContext());
    }

    public SyncAdapter(Context context, boolean autoInitialize, boolean allowParallelSyncs) {
        super(context, autoInitialize, allowParallelSyncs);
    }
    private boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager
            = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
    }

    @Override
    public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
        Log.wtf(TAG, "onPerformSync: ");
        Log.wtf(TAG, "SYNC_EXTRAS_MANUAL: " + extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL));
        Log.wtf(TAG, "SYNC_EXTRAS_EXPEDITED: " + extras.getBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED));

        Log.wtf(TAG, "internte: " + isNetworkAvailable());


        mqttHelper.connect(new IMqttActionListener() {
            @Override
            public void onSuccess(IMqttToken asyncActionToken) {
                Log.wtf(TAG, "onSuccess: ");
                mqttHelper.pub("hello/android", "Finally working via sync adapter praise the lord!!!!");
                // TODO: Get Checkpoints from Realm
                // TODO: publish at once
                // TODO: Disconnect
                mqttHelper.disconnect(new IMqttActionListener() {
                    @Override
                    public void onSuccess(IMqttToken asyncActionToken) {
                        Log.wtf(TAG, "onSuccess: disconnect");
                    }

                    @Override
                    public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                        Log.wtf(TAG, "onFailure: disocnnect");
                    }
                });
            }

            @Override
            public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                Log.wtf(TAG, "onFailure: ", exception);
            }
        });

    }

    @Override
    public void onSyncCanceled() {
        super.onSyncCanceled();
        Log.wtf(TAG, "sync canceled");
    }
}
Run Code Online (Sandbox Code Playgroud)

还有我的Android Manifest与MqttService和SyncAdapter相关的片段:

<application
    ...
    <receiver android:name=".LocationPollingReceiver" />
    <service android:name="org.eclipse.paho.android.service.MqttService"
        android:process=":sync"/>
    <service
        android:name=".LocationPollingService"
        android:exported="false"/>
    <service
        android:name=".sync.AuthenticatorService">
        <intent-filter>
            <action android:name="android.accounts.AccountAuthenticator"/>
        </intent-filter>
        <meta-data
            android:name="android.accounts.AccountAuthenticator"
            android:resource="@xml/authenticator" />
    </service>
    <provider
        android:name=".sync.StubProvider"
        android:authorities="proj.com.fyp.provider"
        android:exported="false"
        android:syncable="true"/>
    <service
        android:name=".sync.SyncService"
        android:exported="true"
        android:process=":sync">
        <intent-filter>
            <action android:name="android.content.SyncAdapter"/>
        </intent-filter>
        <meta-data android:name="android.content.SyncAdapter"
            android:resource="@xml/syncadapter" />
    </service>
</application>
Run Code Online (Sandbox Code Playgroud)

这与手动调用同步有什么关系吗?就像我在下面做的一样?

Account mAccount = MainActivity.CreateSyncAccount(context);
Bundle settingsBundle = new Bundle();
settingsBundle.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
settingsBundle.putBoolean(ContentResolver.SYNC_EXTRAS_EXPEDITED, true);
//settingsBundle.putBoolean(ContentResolver.SYNC_EXTRAS_FORCE, true);
ContentResolver.requestSync(mAccount, AUTHORITY, settingsBundle);
Run Code Online (Sandbox Code Playgroud)

甚至同步通过Settings->Account->Sync now产生相同的结果.

Udd*_*tam 1

让我解释一下。

onPerformSync() 是一个回调,它不由您控制如何/何时调用?这些类型的回调通常是异步任务,可以随时从外部(可以是远程)对象触发。这就是为什么我们通常将这些类型的回调放在 MainThread(UI 线程)中,因为 MainThread 无法在整个应用程序中被杀死。[注意:如果您在不同的进程中执行了服务,那么您也可以从该服务运行 onPerformSync() ]。我这么说的目的是确保在整个应用程序保持运行的过程中,这些回调的变化可以随时执行。

我真的没有看到 onNetworkAvailable() 方法在这里有任何用途。如果您想从您这边执行一些网络操作,请使用此 onNetworkAvailable() 。