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) 用户留在您的应用程序中。您可以通过执行以下操作来说明这一点:
- 您的 IntentService 应该在完成时发送一个有序广播,并提供有关它是否成功的信息。
- 对于您想对此广播做出反应的活动,为它们创建一个基本实现,在 onResume() 中注册一个广播接收器,并在 onPause() 中删除它。如果他们对此做出反应,他们应该取消广播
- 为您的广播创建第二个(但独立的)广播接收器,并在清单中以优先级 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
);
}
}
我遇到了一个问题,需要了解哪个是我想做的事情的最佳解决方案。 (而且我很难理解 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) 用户留在您的应用程序中。您可以通过执行以下操作来说明这一点:
- 您的 IntentService 应该在完成时发送一个有序广播,并提供有关它是否成功的信息。
- 对于您想对此广播做出反应的活动,为它们创建一个基本实现,在 onResume() 中注册一个广播接收器,并在 onPause() 中删除它。如果他们对此做出反应,他们应该取消广播
- 为您的广播创建第二个(但独立的)广播接收器,并在清单中以优先级 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
);
}
}