Reputation: 1171
I'm meeting a problem to understand which is the best solution for what I want to do. (And I've problems to understand ATM how they work exactly)
Often I use Asynctask, but in this case I think it's not what I need.
In an activity (A) I want to start a task which sends datas to a WS and it can take 10-20 secondes to be done. I want to allow the user to do otherthing on the app during this time.
When this task is done, I want to call another activity, but if there are errors, I want to show them in a toast. I want too, to show a progressbar if the user is on this activity (A).
So I see that IntentService can help me, because it's not "linked" to an activity, it works in background etc... but it seems a little complicated to have a link with the UI Thread. (in my case, if there is a problem, I want to do something in my activity A).
The other part, the handler can be used, but if the activity is destroyed, the thread runs always, but how can I "restore" the link with the activity if the users come back on the activity (A) ? (with a static class to save it ?).
So if you have any links/advise/other to give me more explanation, I will appreciate it :) (I readed the Android's doc.)
Upvotes: 0
Views: 1291
Reputation: 2321
First up, use an IntentService - they're designed for exactly this kind of thing. The second part of your question takes a little longer to answer, but bear with me ;-)
Essentially one of two things can happen whilst your IntentService is busy talking to the server: 1) the user navigates away from your, 2) the user stays in your app. You can account for this by doing the following:
Here's a barebones manifest:
<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>
Barebones 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
);
}
}
Upvotes: 2