Android : IntentService 或 Handler

Android : IntentService or Handler

我遇到了一个问题,需要了解哪个是我想做的事情的最佳解决方案。 (而且我很难理解 ATM 的具体工作原理)

我经常使用 Asynctask,但在这种情况下,我认为这不是我需要的。

在 activity (A) 中,我想开始一个将数据发送到 WS 的任务,它可能需要 10-20 秒才能完成。我想允许用户在此期间在应用程序上做其他事情。

完成此任务后,我想调用另一个 activity,但如果有错误,我想在 toast 中显示它们。我也想要,如果用户在此 activity (A) 上,则显示进度条。

所以我看到 IntentService 可以帮助我,因为它不是 "linked" 到 activity,它在后台工作等...但是 [=38 似乎有点复杂=] 与 UI 线程。 (就我而言,如果有问题,我想在 activity A 中做一些事情)。

另一部分,handler可以用,但是如果activity被销毁了,线程一直运行,但是我怎么"restore" link 和activity 如果用户返回 activity (A) ? (用静态的class来保存吗?)。

因此,如果您有任何 links/advise/other 给我更多解释,我将不胜感激 :)(我阅读了 Android 的文档。)

首先,使用 IntentService - 它们正是为这类事情而设计的。您问题的第二部分需要更长的时间来回答,但请耐心等待 ;-)

当您的 IntentService 正忙于与服务器对话时,基本上可能会发生以下两种情况之一:1) 用户离开您的应用程序,2) 用户留在您的应用程序中。您可以通过执行以下操作来说明这一点:

  1. 您的 IntentService 应该在完成时发送一个有序广播,并提供有关它是否成功的信息。
  2. 对于您想对此广播做出反应的活动,为它们创建一个基本实现,在 onResume() 中注册一个广播接收器,并在 onPause() 中删除它。如果他们对此做出反应,他们应该取消广播
  3. 为您的广播创建第二个(但独立的)广播接收器,并在清单中以优先级 0 注册它,这样它总是最后知道您的 IntentService 完成。此接收器负责创建用户点击的通知,这会将他们带到您应用中的相关位置。

这是一个准系统清单:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="bubblebearapps.co.uk.blah" >

<permission android:name="change_this_name"
    android:label="my_permission"
    android:protectionLevel="dangerous"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >

    <uses-permission android:name="change_this_name"/>

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <receiver
        android:name=".MyReceiver"

        android:enabled="true"
        android:exported="false"
        android:permission="change_this_name">
        <intent-filter android:priority="0">
            <action android:name="action_name_here"/>

        </intent-filter>
    </receiver>
</application>

</manifest>

准系统activity:

public class MainActivity extends AppCompatActivity {

public static final String YOUR_ACTION = "this_action_matches_the_one_in_the_manifest";
public static final String YOUR_PERMISSION = "this_permission_matches_the_one_in_the_manifest";


private InterceptsReciever mReceiver;

private void doSomethingWithBroadcast(Intent intent) {
    // this method must return quickly! If you've got something long to do, do it on a background thread
}

@Override
protected void onResume() {
    super.onResume();
    mReceiver = new InterceptsReciever(this);
}

@Override
protected void onPause() {
    unregisterReceiver(mReceiver);
    super.onPause();
}

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

public static class InterceptsReciever extends BroadcastReceiver {


    private final MainActivity mainActivity;

    public InterceptsReciever(MainActivity mainActivity) {
        this.mainActivity = mainActivity;
        IntentFilter filter = new IntentFilter(YOUR_ACTION);
        filter.setPriority(1); //anything above the manifest. You could have higher priorities for nested fragments or whatever if you like....

        mainActivity.registerReceiver(this,
                filter, 
                YOUR_PERMISSION,
                null);
    }

    @Override
    public void onReceive(Context context, Intent intent) {

        if (YOUR_ACTION.equals(intent.getAction())) {

            mainActivity.doSomethingWithBroadcast(intent);
            abortBroadcast(); // this prevents other the manifest broadcast being called

        }

    }
}


/**
 * Example of how to send broadcasts
 * @param context
 */
public static void sendBroadcast(Context context){

    Intent intent = new Intent(YOUR_ACTION);

    context.sendOrderedBroadcast(
            intent,
            YOUR_PERMISSION        // this protects your broadcast from being seen by just anyone
    );

}



}