Tobias Moe Thorstensen
Tobias Moe Thorstensen

Reputation: 8981

onDestroy, killing a running thread

I have a method like this in my class which extends Activity

@Override
public void onDestroy() {
    Log.i("onDestory: ", "Inside OnDestory!");
    bluetoothCommunicator.destroyedApp();
    super.onDestroy(); 
}

The method destroyedApp() look like this:

public void destroyedApp() {
        if(server != null)
            server.destroy();   
}

Where server is an Instance of a class which extends Thread

Here is the scenario:

I'm opening the application for the first time, inside my onCreate method, I create a new instance of the bluetooth class which sets up the BluetoothServerSocket, this works fine and I'm able to transfer files to my phone.

This also works when I have my application in the background, because the thread is still alive.

But

When I'm killing the application, according to the Activity Life Cycle

Activity Life Cycle here

The onDestroy() method should be called by the Android Framework. And when I'm launching the application once more, the onCreate method should be called, but it doesnt seems that an instance of the BluetoothServerSocket is being created. I have no LogCat info, because the device which sends the bluetooth file, only says:

Error Log:
Write Error: 
Transport endpoint is not connected
__obex_connect:
error=-2
Unable to connect to the server
Error

Which tells me that the BluetoothServerSocket is not "alive"

Any suggestion on how I can accomplish this?

Upvotes: 2

Views: 3784

Answers (3)

Robin Chander
Robin Chander

Reputation: 7415

Since I cannot comment, I am posting here. As, commented by Egor I dont think you can call onStop() from within onDestroy(), Android will itself call onStop() following onPause() depending on the memory. Now, note that stop(), suspend() and destroy() methods of thread are deprecated, the only safe way of terminating a thread is to have thread exit its run(). Now, when you are calling server.destroy(), there is a possibility that it still holds some link in the memory and therefore Garbage collector will not be able to garbage collect your activity. Hence, I believe this could be the possible reason why your onDestroy is not called. Point me if I am worng.

Upvotes: 2

Jong
Jong

Reputation: 9125

How are you killing your application? I was looking for a solution for your problem in the Application class and I came across this information about the onTerminate() method:

This method is for use in emulated process environments. It will never be called on a production Android device, where processes are removed by simply killing them; no user code (including this callback) is executed when doing so.

I remember I had a similar problem in one of my apps, where some components' onDestroy() method was not called because I used the "Clear memory" button in the Task Manager (Samsung Galaxy 2)

Upvotes: 1

Anup Cowkur
Anup Cowkur

Reputation: 20563

There is generally no guarantee that the onDestroy() method will be called at all. According to the docs:

Note: do not count on this method being called as a place for saving data! For example, if an activity is editing data in a content provider, those edits should be committed in either onPause() or onSaveInstanceState(Bundle), not here. This method is usually implemented to free resources like threads that are associated with an activity, so that a destroyed activity does not leave such things around while the rest of its application is still running. There are situations where the system will simply kill the activity's hosting process without calling this method (or any others) in it, so it should not be used to do things that are intended to remain around after the process goes away.

Derived classes must call through to the super class's implementation of this method. If they do not, an exception will be thrown.


So I would first test if it is being called reliably.

Also, you are callling super.onStop() in your onDestroy(). It should be super.onDestroy()

Upvotes: 3

Related Questions