Android Service continues to disconnect when closing the application - java

I had previously managed to get my service to continue running. But today after I went back to the application to keep working with the app I noticed that the service gets disconnected after the app is closed which was not happening before.
I start the service in my main activity like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
if(savedInstanceState == null) {
setContentView(R.layout.activity_main);
Intent i = new Intent(MainActivity.this, SystemWebService.class);
SystemWebService.setMain(this);
MainActivity.this.startService(i);
}
The code in the SystemWebService class looks like this:
public class SystemWebService extends Service {
private static WebView webdemo;
private static MainActivity ma;
//Context dex;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId){
// let the service continue until stopped
Toast.makeText(this, "Service has started", Toast.LENGTH_SHORT).show();
return START_STICKY;
}
#Override
public void onDestroy(){
super.onDestroy();
Toast.makeText(this, "Service has been destroyed", Toast.LENGTH_SHORT).show();
}
#Override
public void onCreate() {
super.onCreate();
}
public static void setMain(MainActivity a) {
ma = a;
SystemWebService sws = new SystemWebService();
sws.setView();
}
}
This is the code that sets the webview
public void setView() {
webdemo = (WebView) ma.findViewById(R.id.webdemo);
webdemo.addJavascriptInterface(new SystemWebService.WebAppInterface(this), "Android");
webdemo.setWebViewClient(new WebViewClient(){
#Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest url){
return false;
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
webdemo.getSettings().setJavaScriptEnabled(true);
webdemo.getSettings().setDomStorageEnabled(true);
webdemo.getSettings().setAllowFileAccessFromFileURLs(true);
webdemo.getSettings().setAllowUniversalAccessFromFileURLs(true);
}
webdemo.loadUrl("file:///android_asset/_wv.html");
}
The webview establishes a connection to our server and I would normally see data display on the logs. Before I would continue to see the flux of data passing even after the application was closed but as of right not I am not seeing anything, only the message "Application terminated".
I can't seem to understand what is happening.

Passing a reference of your activity to the service, and keeping a static instance of it is not the recommended way of development. It can lead to unexpected behaviour during the life cycle of your activity or the service.
Use the Bound Services instead. Check the documentation here : https://developer.android.com/guide/components/bound-services.html

Related

Checking if the internet connection is lost at runtime

Good day.
I know how to check if there is an internet connection available, my problem is that I want to present the user an AlertDialog that prevents action except trying again whenever the connection is lost or deactivated. What I don't know is how to code it only one time, so I don't need to replicate it manually in all activities.
I tried using Observer Pattern, and initialize it in SplashActivity(Launcher Activity).
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
ObservedObject observedObject = new ObservedObject();
observedObject.addObserver(new ObserverInternetConnection());
}
public class ObservedObject extends Observable {
private boolean isConnected;
public boolean isConnected() {
return isConnected;
}
public void setConnected(boolean connected) {
isConnected = connected;
setChanged();
notifyObservers();
}
public class ObserverInternetConnection implements Observer {
#Override
public void update(Observable observable, Object o) {
if (observable instanceof ObservedObject) {
if (observable.hasChanged())
//alert is a method to show toast message
alert("connection changed");
if (((ObservedObject) observable).isConnected)
alert("connected");
else
alert("disconnected");
}
}
}
It worked when I manually set the observedObject connection. But I want to avoid doing so. Is there a way to do this automatically? I was thinking of using another thread, but how could I do so?
another problem is that the way i check the internet connection is using ConnectivityManager but it need me to pass the context and the context can (and will) change throughout the application, how can I overcome so? Is there any other approach for the problem?
I would suggest to create BaseActivity where you are initializing connectivity change listener (Observer in your case) and extend this activity with Splash, Main and other activities that you are using.
This way you are going to avoid code duplication.
Also don't forget to unregister listeners when activity is destroyed.
Also you dont need to use different threads. Here is example how to listen connectivity changes in Activity:
Register receiver first:
#Override
public void register(Context context) {
initReceiver();
final IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(receiver, intentFilter);
}
receiver
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (isOnline()) {
hideNoConnectionError();
} else {
showNoConnectionError();
}
}
};
and isOnline()
val isOnline: Boolean
get() {
return try {
val connectivityManager = context.getSystemService(
Context.CONNECTIVITY_SERVICE) as ConnectivityManager
connectivityManager.activeNetworkInfo != null &&
connectivityManager.activeNetworkInfo.isConnected
} catch (exception: Exception) {
false
}
}
sorry, last method is written in Kotlin, but I think it is completely understandable
One additional approach if your minimal SDK version >= N(24) would be to subscribe to ConectivityManager in Application class. In order to prevent user from interaction start transparrent activity on top with some shadowed background stating that connection lost. This is not ideal approach but you will not need to stick to inheritance.
TestApplication.java
public class TestApplication extends android.app.Application {
private static final String TAG = "TestApplication";
#Override
public void onCreate() {
super.onCreate();
ConnectivityManager m = (ConnectivityManager) getSystemService(Service.CONNECTIVITY_SERVICE);
m.registerDefaultNetworkCallback(new ConnectivityManager.NetworkCallback() {
#Override
public void onAvailable(Network network) {
Log.e(TAG, "onAvailable: ");
startActivity(ConnectionLostScreen.createIntentHideSplashOnNetworkRecovery(TestApplication.this));
}
#Override
public void onLost(Network network) {
Log.e(TAG, "onLost: ");
startActivity(ConnectionLostScreen.createShowSplashOnNetworkFailure(TestApplication.this));
}
});
}
}
ConnectionLostScreen.java
public class ConnectionLostScreen extends AppCompatActivity {
private final static int SHOW = 1;
private final static int HIDE = 2;
private final static String EXTRA_NAME = "ACTION";
public static Intent createShowSplashOnNetworkFailure(Context app) {
Intent intent = new Intent(app, ConnectionLostScreen.class);
intent.putExtra(EXTRA_NAME, SHOW);
intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT| Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_ANIMATION);
return intent;
}
public static Intent createIntentHideSplashOnNetworkRecovery(Context app) {
Intent intent = new Intent(app, ConnectionLostScreen.class);
intent.putExtra(EXTRA_NAME, HIDE);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
return intent;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
if (getIntent() != null) handleIntent(getIntent());
}
#Override
public void onBackPressed() {
//disabled so user would not be able to close this activity.
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent != null) handleIntent(intent);
}
void handleIntent(Intent intent) {
int value = intent.getIntExtra(EXTRA_NAME, 0);
if (value == 0 || value == HIDE) {
finish();
return;
}
}
}
Theme for ConnectionLostScreen would be.
<style name="Theme.Transparent" parent="AppTheme">
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">#android:color/transparent</item>
<item name="android:windowContentOverlay">#null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
Pros:
No inheritance.
Independent and works across application
No activity lifetime tracking
No need for Activity context as entire Activity acts like dialog.
Custom layout, graphic, animation could be integrated
No user action needed because when connection restored ConnectionLostScreen will be closed.
Cons:
Activity flow management for ConnectionLostScreen (making it
singleTop etc.)
Hard to make granular control if only certain
screens should be covered
Animations for Activity transitions

show app lock pattern dialog when unlocking the phone

I have MainActivity and on its onResume method I call pattern lock to create and confirm user identity. User visits and leave this MainActivity back and forth while active on the app as well as when phone is in sleep mode and user unlocks it. These both scenarios will call onRestart, onStart and onResume methods, but I only want to revoke the pattern in unlock scenario.
handlePattern() method needs a proper distinguishing to be called.
How to distinguish this when I call the handlePattern method ?
MainActivity.class
onCreate(){}
onResume(){
//help needed to know that user is just visiting activity in app back and forth
or came back after unlocking the screen.
if(isPatternCallRequired){
handlePattern()
}
}
In your onStop() method call you can check if the player is in sleep mode and cache the boolean.
PowerManager pm = (PowerManager)
_context.getSystemService(Context.POWER_SERVICE);
boolean isInSleepMode = !pm.isScreenOn();
Check for the build version
if( Build.VERSION.SDK_INT >= 20)
// use isInteractive()
else
// use isScreenOn()
in onRestart which will get called when you resume from sleep - based on the cached value you can show the pattern to unlock.
You may need to reset the cached value once you are done using it.
onResume may not be a right API for the call as it will be called even when your activity loads.
Edited answer based on your comment
You can try ActivityLifecycleCallbacks too like this,
First, Register your Application in your Application class.
public class StackApp extends Application {
private static final String TAG = StackApp.class.getSimpleName();
public static final String INTENT_ACTION_APP_STATE_CHANGE = "intent_action_app_state_change";
public static final String INTENT_DATA_IS_IN_BACKGROUND = "intent_data_is_in_background";
private static int mNumRunningActivities = 0;
private static AtomicBoolean mIsAppInForeground = new AtomicBoolean();
#Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= 14) {
// registerActivityLifecycleCallbacks is supported only from the SDK version 14.
registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
#Override
public void onActivityStarted(Activity activity) {
mNumRunningActivities++;
if (mNumRunningActivities == 1) {
notifyAppState(false);
Log.i(TAG, "APP IN FOREGROUND");
}
}
#Override
public void onActivityResumed(Activity activity) {
}
#Override
public void onActivityPaused(Activity activity) {
}
#Override
public void onActivityStopped(Activity activity) {
mNumRunningActivities--;
if (mNumRunningActivities == 0) {
notifyAppState(true);
}
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
#Override
public void onActivityDestroyed(Activity activity) {
}
});
}
}
/**
* To notify App state whether its in ForeGround or in Background
*
* #param isInBackground
*/
private void notifyAppState(boolean isInBackground) {
if (isInBackground) {
mIsAppInForeground.set(false);
} else {
mIsAppInForeground.set(true);
}
sendAppStateChangeBroadcast(isInBackground);
}
public static boolean isInForeground() {
return mIsAppInForeground.get();
}
private void sendAppStateChangeBroadcast(boolean isInBackground) {
Log.i(TAG, "sendAppStateChangeBroadcast - isInBackground : " + isInBackground);
Intent intent = new Intent();
intent.setAction(INTENT_ACTION_APP_STATE_CHANGE);
intent.putExtra(INTENT_DATA_IS_IN_BACKGROUND, isInBackground);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
And register the broadcast and listen whether the App is going background or foreground like this Sample Activity example
public class SampleMyActivity extends AppCompatActivity {
private OnAppStateReceiver mAppStateReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample_my);
mAppStateReceiver = new OnAppStateReceiver();
IntentFilter filter = new IntentFilter(StackApp.INTENT_ACTION_APP_STATE_CHANGE);
LocalBroadcastManager.getInstance(this).registerReceiver(mAppStateReceiver, filter);
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mAppStateReceiver != null) {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mAppStateReceiver);
}
}
private class OnAppStateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (!TextUtils.isEmpty(action) && StackApp.INTENT_ACTION_APP_STATE_CHANGE.equalsIgnoreCase(action)) {
boolean isGoingBackground = intent.getBooleanExtra(StackApp.INTENT_DATA_IS_IN_BACKGROUND, false);
if (isGoingBackground) {
//Your app is not vissible to the use
} else {
// App is visible to the user.
}
}
}
}
}
Note: If you want to listen in Multiple Activity you can create a base
class and add the listener there and you can do the operation, In that
case you can reduce a lot of code.

How to call AsyncTask from a service or better way for background updating

I am working on app, right now it pulls data from twitter and updates the IU on a button press. I want to automate that so it will update every hour in the background and eventually get it to send a notification from the background as well.
I can call an AsyncTask with an update button which accesses twitter and updates text and icons in a UI thread. I also have a service which I can turn on and off with a checkbox. Can I call my AsyncTask from the service and get it to auto update or is there something else I should be doing instead?
Here is my stripped down code for the Main:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lastUpdate = (TextView) findViewById(R.id.lastUpdate);
//checkbox starts and stops service "TheService"
CheckBox checkBox = (CheckBox) findViewById(R.id.check_box);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
startService(new Intent(MainActivity.this, TheService.class));
}else{
stopService(new Intent(MainActivity.this, TheService.class));
}
}
});
}
//This function is called when button is clicked.
public void startTask(View view) {
myAsyncTask mTask = new myAsyncTask();
mTask.execute("abc", "10", "Hello world");
}
public class myAsyncTask extends AsyncTask<String, Integer, Void> {
#Override
protected Void doInBackground(String... arg) {
try {
//accesses twitter here
} catch (TwitterException te) {
System.exit(-1);
}
//New thread is created because this function can't update UI Thread.
runOnUiThread(new Thread() {
public void run() {
TextView lastUpdate = (TextView) findViewById(R.id.lastUpdate);
//change text and icons on screen here
lastUpdate.setText("Last updated: " + currentTime);
}
});
return null;
}
}
}
Service:
public class TheService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, "Service created!", Toast.LENGTH_LONG).show();
}
#Override
public void onDestroy() {
Toast.makeText(this, "Service stopped", Toast.LENGTH_LONG).show();
}
}
its better to use thread inside service instead for your server request or repeated or fix interval request and use broadcast receiver or LocalBroadcastManager and send that broadcast from service or thread to update ui in your activity do not forget to register and unregister reciver when your app is on resume(), on pause() or on stop() state otherwise it leak.keep in mind that Service is not background Thread is simple balnk ui you have to create thread inside service for server request. also you can find better SO thread and tutorial by searching regarding your question. hope you will understand.

Access from AsyncTask to Application Class or any other Global variables from any Classes

I can't access from AsyncTask to Application Class, or issue with SharedPreferences with last updated data, etc..
Basically why I need my Global variable is to keep track currently active activity, and it should be accessable from any type of class, like Activity, AsyncTask, Service, Receiver, Application, Etc...
I know there is lot of questions=answers in here, but none of those helped me.
I tried several ways to do this, but couldn't find any real resolution for this.
With SharedPreferences, I can use it, but after preferences updated and readed, returned previous value, works only after restart app.
With Application Class, no luck, can't access to Application from AsyncTask and service
Service runs AsyncTask on every 5sec, and AsyncTask should know if MainActivity is opened and running, so it can update contents to it.
I got pretty much everything working but, with this, I spend way too many hours on searching.
So please, if anybody can help me with this, it would be nice. :)
Here is little example how I do..
MainActivity.java
public class MainActivity extends Activity {
private boolean active = false;
SharedPreferences prefs;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
this.prefs = context.getSharedPreferences("com.my.app", Context.MODE_PRIVATE);
storeActivity("MainActivity");
this.active = true;
((App) this.getApplication()).setTopActivity("MainActivity");
}
public void storeActivity(String TOP_ACTIVITY) {
SharedPreferences.Editor editor = prefs.edit();
editor.putString("TOP_ACTIVITY", TOP_ACTIVITY);
editor.apply();
editor.commit();
}
#Override
public void onResume() {
super.onResume();
((App) this.getApplication()).setTopActivity("MainActivity");
this.active = true;
storeActivity("MainActivity");
}
#Override
public void onPause() {
super.onPause();
((App) this.getApplication()).setTopActivity("");
this.active = false;
storeActivity("");
}
#Override
public void onStart() {
super.onStart();
((App) this.getApplication()).setTopActivity(ACTIVITY_NAME);
this.active = true;
storeActivity("MainActivity");
}
#Override
public void onStop() {
super.onStop();
((App) this.getApplication()).setTopActivity("");
this.active = false;
storeActivity("");
}
}
Here is my Application Object,
App.java
public class App extends Application {
private String TOP_ACTIVITY;
public String getTopActivity() {
return TOP_ACTIVITY;
}
public void setTopActivity(String CURRENT_ACTIVITY) {
this.TOP_ACTIVITY = CURRENT_ACTIVITY;
}
public static Application getApplication() {
return new App();
}
}
And here is some AsyncTask getting information from server
Socket.java
public class SocketUpdater extends AsyncTask<String,Void,String> {
private Context context;
private SharedPreferences prefs;
public SocketUpdater(Context context) {
this.context = context;
this.prefs = context.getSharedPreferences("com.my.app", Context.MODE_PRIVATE);
}
#Override
protected String doInBackground(String... arg0) {
StringBuffer result = new StringBuffer("");
return new String(result);
}
#Override
protected void onPostExecute(String result) {
Toast.makeText(context, "RESULT: " + result, Toast.LENGTH_SHORT).show();
String TOP_ACTIVITY = ((App) this.getApplication()).getTopActivity();
// THIS CANT WORK, NO this.getApplication()!!!
boolean MainActivityActive = MainActivity.active;
// THIS RETURNS ME FALSE ALL THE TIME
SharedPreferences.Editor editor = prefs.edit();
String PREF_TOP_ACTIVITY = prefs.getString("TOP_ACTIVITY", "");
if(MainActivityActive) {
Toast.makeText(context, "NEVER FIRES!", Toast.LENGTH_LONG).show();
}
if(TOP_ACTIVITY.equals("MainActivity")) {
Toast.makeText(context, "NEVER FIRES!", Toast.LENGTH_LONG).show();
}
if(PREF_TOP_ACTIVITY.equals("MainActivity")) {
Toast.makeText(context, "NEVER FIRES!", Toast.LENGTH_LONG).show();
}
}
}
Why not use "Otto" library from Square? You can send objects with ease between activity and service. I'm using it within my application for similar purpose.
I spent days for searching what causes the problem.
I found simple solution for this, and got all methods working like I wanted.
The thing was that I had my service running own separated process like this:
<service android:name="fi.hgs.apps.MyService"
android:process=":myService"
</service>
And just removed android:process=":myService" from AndroidManifest.xml

How to prevent a Fragment from being added when an Activity is closing

I am creating an Activity which communicates with a Service to download some data from internet via POST method. To do this, I use Messenger. Here is my code to make it clearer for you:
My onCreated() method:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_comments);
CommentsHandler commentsHandler = new CommentsHandler(this, savedInstanceState);
Messenger messenger = new Messenger(commentsHandler);
Intent serviceIntent = new Intent(this, WindowService.class);
serviceIntent.putExtra("messenger", messenger);
serviceIntent.putExtra("state", 888);
serviceIntent.putExtra("number", getIntent().getStringExtra("number"));
startService(serviceIntent);
}
The code in my Service's thread to post the result data to the Activity via the Messenger object:
/** ... **/
Messenger messenger = intent.getParcelableExtra("messenger");
/** ... **/
Message resultMsg = this.obtainMessage();
resultMsg.obj = jParser.getArrayList(); //This is an ArrayList of my downloaded data.
messenger.send(resultMsg);
The code in the Activity to handle the Message from the Service:
public static class CommentsHandler extends Handler {
Bundle mSavedInstanceState;
ActionBarActivity activity;
public CommentsHandler(Activity a, Bundle savedInstanceState) {
activity = (ActionBarActivity) a;
mSavedInstanceState = savedInstanceState;
}
#Override
public void handleMessage(Message msg) {
comments = (ArrayList<HashMap<String, String>>) msg.obj;
if (mSavedInstanceState == null && msg.arg1 != 793) {
activity.getSupportFragmentManager().beginTransaction()
.add(R.id.container, new CommentsFragment()).commit();
} else if (msg.arg1 == 793) { //793 is my preferred code to determine
//if the internet connection could not be
//established when the Service was trying
//to download the data.
activity.finish();
}
}
}
The problem is: if I open the Activity and close it before the data is downloaded, this code .add(R.id.container, new CommentsFragment()).commit(); gives me the error Can not perform this action after onSaveInstanceState, because this code only gets executed after the data in my Service is processed and sent via the Messenger object, but at that time the Activity is already closed by the user so the Fragment cannot be added. How to solve this issue? How to check if the Activity is not closed/being closed before adding the Fragment? Or, better, how to stop the thread in which that code is running on Activity's onDestroy() method so it doesn't get executed if the Activity is closed? Thanks in advance!
In your activity, you should create a boolean to check if the activity is visible or not:
public ActionBarActivity extends Activity {
private boolean isActivityVisible = false;
#Override
protected void onResume(){
isActivityVisible = true;
}
#Override
protected void onPause(){
isActivityVisible = false;
}
public boolean isVisible(){
return this.isActivityVisible;
}
}
And then you modify your Handler class definition:
public static class CommentsHandler extends Handler {
Bundle mSavedInstanceState;
ActionBarActivity activity;
public CommentsHandler(Activity a, Bundle savedInstanceState) {
activity = (ActionBarActivity) a;
mSavedInstanceState = savedInstanceState;
}
#Override
public void handleMessage(Message msg) {
// here you check if your activity is no longer visible and then break up
if(activity == null || !activity.isVisible())
return;
comments = (ArrayList<HashMap<String, String>>) msg.obj;
if (mSavedInstanceState == null && msg.arg1 != 793) {
activity.getSupportFragmentManager().beginTransaction()
.add(R.id.container, new CommentsFragment()).commit();
} else if (msg.arg1 == 793) { //793 is my preferred code to determine
//if the internet connection could not be
//established when the Service was trying
//to download the data.
activity.finish();
}
}
}
The smallest change would be to have a boolean field in the Activity, setting it to true in onResume() and to false in onPause(), and check its value in handleMessage() (i.e. ignore the message if the flag is currently false).
Another option, instead of using Messenger and handleMessage(), do this with a BroadcastReceiver. Register the receiver in onResume() and unregister it in onPause(). That way the broadcast from the service will be simply ignored.
Both solutions are basically the same, anyway, but broadcasts are somewhat "higher level".
This assumes that you're not interested in the Service's result if the activity is paused. If you are (for example, if you switch out of the application and back in, and you need to display the update) then you should put the received data in a field and process it on the following onResume().
Your way of doing this is different than how I would handle it but using what you have I would make these adjustments:
public static class CommentsHandler extends Handler {
Bundle mSavedInstanceState;
ActionBarActivity activity;
public CommentsHandler(Activity a, Bundle savedInstanceState) {
activity = (ActionBarActivity) a;
mSavedInstanceState = savedInstanceState;
}
public void setActivity(Activity a){
activity = a;
}
#Override
public void handleMessage(Message msg) {
if(activity == null){
return;
}
comments = (ArrayList<HashMap<String, String>>) msg.obj;
if (mSavedInstanceState == null && msg.arg1 != 793) {
activity.getSupportFragmentManager().beginTransaction()
.add(R.id.container, new CommentsFragment()).commit();
} else if (msg.arg1 == 793) { //793 is my preferred code to determine
//if the internet connection could not be
//established when the Service was trying
//to download the data.
activity.finish();
}
}
}
Then I would use your activities onPause()/onResume() methods to like this:
#Override
protected void onPause() {
super.onPause();
commentsHandler.setActivity(null);
}
#Override
protected void onResume() {
super.onResume();
commentsHandler.setActivity(this);
}

Categories

Resources