Creating and killing threads in Android - android

I have an application that creates a thread to do some work. When the work is done I kill the thread. Problem is that every time I do kill the thread, the heap seems to have increased by 10k? To test further I did the following in a 1ms handler.
TestThread new_thread = new TestThread();
new_thread = null;
Every time I run this I see the heap increase under DDMS. The TestThread does nothing. It has no code. Its just an empty thread.
import android.util.Log;
public class TestThread extends Thread {
public TestThread () {
Log.d("TESTTHREAD","Constructed");
}
public void run() {
Log.d("TESTHREAD","Run");
}
}
Any idea why this is?

The myThread.stop() method is deprecated because it might leave the application in an
unpredictable state. Instead, use the following when needed, such as in the onStop()
method of the parent component:
//use to stop the thread myThread
if(myThread != null) {
Thread dummy = myThread;
myThread = null;
dummy.interrupt();
}

Related

Thread.sleep() vs handler.postDelay() to execute network call in every 30sec

I want perform a network call in every 30sec to push some metrics to Server. Currently I am doing it using thread.sleep(). I found some articles saying thread.sleep() has some drawbacks. I need to know am I doing it right? or Replacing the thread with Handler will improve my code?
public static void startSending(final Context con) {
if (running) return;
running = true;
threadToSendUXMetrics = new Thread(new Runnable() {
#Override
public void run() {
do {
try {
Thread.sleep(AugmedixConstants.glassLogsPushInterval);
} catch (InterruptedException e) {
mLogger.error(interrupt_exception + e.getMessage());
}
// to do to send each time, should have some sleep code
if (AugmedixConstants.WEBAPP_URL.equals(AugmedixConstants.EMPTY_STRING)||!StatsNetworkChecker.checkIsConnected(con)) {
Utility.populateNetworkStat();
mLogger.error(may_be_provider_not_login_yet);
} else
sendUXMetrics();
} while (running);
if (!uxMetricsQueue.isEmpty()) sendUXMetrics();
}
});
threadToSendUXMetrics.start();
}
If You are using only one thread in the network, then usage of the thread.sleep() is fine. If there are multiple threads in synchronization, then the thread.sleep() command will block all the other threads that are currently running.
As per the details you've provided, there is only one thread present which isn't blocking any other active threads which are running in synchronization, so using thread.sleep() shouldn't be a problem.
Use Handler.postDelayed to schedule tasks if you are working in UI Thread and Thread.sleep if you are working in background thread.
Apparently you are sending some data using network, you must do it in the background thread, hence Thread.sleep is recommended.
Simple is:
Thread.sleep(millisSeconds): With this method, you only can call in background tasks, for example in AsyncTask::doInBackground(), you can call to delay actions after that. RECOMMENDED CALL THIS METHOD IN BACKGROUND THREAD.
Handler().postDelayed({METHOD}, millisSeconds): With this instance, METHOD will trigged after millisSeconds declared.
But, to easy handle life cycle of Handler(), you need to declare a Handler() instance, with a Runnable instance. For example, when your Activity has paused or you just no need call that method again, you can remove callback from Handler(). Below is example:
public class MainActivity extends Activity {
private Handler mHandler = Handler();
public void onStart(...) {
super.onStart(...)
this.mHandler.postDelayed(this.foo, 1000)
}
public void onPaused(...) {
this.mHandler.removeCallback(this.foo)
super.onPaused(...)
}
private Runnable foo = new Runnable() {
#Override
public void run() {
// your code will call after 1 second when activity start
// end remove callback when activity paused
// continue call...
mHandler.postDelayed(foo, 1000)
}
}
}
The code above just for reference, I type by hand because don't have IDE to write then copy paste.

How to implement a more flexible AsyncTask?

while it is very convenient to use, from my understanding, AsyncTask has two important limitations:
doInBackground of any instances will share the same worker
thread, i.e. one long running AsyncTasks can block all others.
execute, onPostExecute and other "synchronizing" methods must/will always be executed on the UI-thread, i.e. not on the Thread, which wants to start the task.
I ran into trouble, when I tried to reuse some existing AsyncTasks in a background IntentService that are responsible for the client-server communication of my app. The tasks of the service would fight over time in the worker thread with those of the UI activities. Also they would force the service to fall back onto the UI-thread, although that service should perform its work quietly in the background.
How would I go about removing/circumventing these limitations? I basically want to achieve:
A framework that closely resembles AsyncTask (because I need to migrate a lot of critical code there).
Each instance of such a task should run its doInBackground on its own thread instead of a single worker thread for all instances.
Edit: Thx to VinceFR for pointing out this can be achieved by simply calling executeOnExecutor instead of execute.
The callbacks like onPostExecute should be called on the same thread that started the task by calling execute, which should not need to be the UI-thread.
I figure, I'm not the first person to require something like this. Therefore I wonder: Is there already some third-party library that can be recommended to accomplish this? If not, what would be a way to implement this?
Thanks in advance!
The solution looks like this:
All classes that spawn AsyncTasks that might interfere with each other get their own Executor like this one (make that elaborate as you like using thread pools etc.):
private Executor serviceExecutor = new Executor() {
public void execute(Runnable command) {
new Thread(command).start();
}
};
As pointed out by VinceFR you can run an AsyncTask on a given Executor by calling it like this (where payload are the parameters that you would regularly pass to a task):
task.executeOnExecutor(serviceExecutor, payload);
However, this breaks backwards-compatibility to Gingerbread and earlier. Also, if you want to support Honeycomb, you need to make sure, this call happens on the UI thread. Jelly Bean will take care of this automatically.
Now the trickier part: Keeping the service running on its own thread. As many things in Android this seems harder than it needs to be (or maybe I'm lacking some information here). You can't use an IntentService, because that will shut down automatically the first time an AsyncTask takes over and let's the onHandleIntent callback complete.
You need to setup your own thread and event loop on the service:
public class AsyncService extends Service {
private static final String TAG = AsyncService.class.getSimpleName();
private class LooperThread extends Thread {
public Handler threadHandler = null;
public void run() {
Looper.prepare();
this.threadHandler = new Handler();
Looper.loop();
}
}
private LooperThread serviceThread = null;
private Handler serviceThreadHandler = null;
#Override
// This happens on the UI thread
public void onCreate() {
super.onCreate();
}
#Override
// This happens on the UI thread
public int onStartCommand(Intent intent, int flags, int startId) {
this.serviceThread = new LooperThread();
this.serviceThread.start();
while(this.serviceThread.threadHandler == null) {
Log.d(TAG, "Waiting for service thread to start...");
}
this.serviceThreadHandler = this.serviceThread.threadHandler;
this.serviceThreadHandler.post(new Runnable() {
#Override
public void run() {
doTheFirstThingOnTheServiceThread();
}
});
return Service.START_STICKY;
}
// doTheFirstThingOnTheServiceThread
}
No you need to make sure that each time an AsyncTask returns to the UI thread, you end up in your service thread instead:
// This happens on the serviceThread
private void doTheFirstThingOnTheServiceThread() {
// do some stuff
// here we can reuse a class that performs some work on an AsyncTask
ExistingClassWithAsyncOperation someUsefullObject = new ExistingClassWithAsyncOperation();
// the existing class performs some work on an AsyncTask and reports back via an observer interface
someUsefullObject.setOnOperationCompleteListener(new OnOperationCompleteListener() {
#Override
// This happens on the UI thread (due to an ``AsyncTask`` in someUsefullObject ending)
public void onOperationComplete() {
serviceThreadHandler.post(new Runnable() {
#Override
public void run() {
doTheSecondThingOnTheServiceThread();
}
});
}
}
someUsefulObject.performOperation();
}
// This happens on the serviceThread
private void doTheSecondThingOnTheServiceThread() {
// continue working on the serviceThread
}
So, this works for me. I'd be delighted to see a simpler solution for this. Note that the solution requires the service to know that is will be called back by the ExistingClassWithAsyncOperation on the UI thread. I don't particularly like this dependency, but don't know how to do better right now. However, I don't have to rewrite a lot of existing classes that perform asynchronous operations using AsyncTask.

Stop Previously running thread which was created in previous class in android

I just need to stop a thread which was created in previous run time of the same application. This is the scenario. I'm retrieving data from database for the notification using thread in background, But when I start that application again, number of threads are increasing. I need to stop this. I think its better to stop the background running thread in onCreate() method of the application's main class. But noway to do it. Please help me on this thing as soon as possible.
Thanks and Best Regards,
Shehan.
Keep a static reference to the running Thread in your activity class. Inside your thread you need to have a boolean variable you can set or a method you can call that will cause your thread to complete. In onCreate() you can check if you have a running thread, and if so, tell it to stop. Here's a code example:
In your activity:
private static Thread myThread;
In your activity, when you create the thread:
if (myThread != null) {
if (myThread.isAlive()) {
myThread.running = false; // Tell the thread to stop running now
}
}
myThread = new Thread(...);
myThread.start();
In your thread:
public boolean running = true; // Initator of this thread should set this to false to make the thread complete
public void run() {
while (running) {
// do whatever your thread does in a loop
}
}
You can stop the ruuning threads onDestroy() of activity.
please find the below eg:
static boolean stopThread=false;
public myThread implements Ruunable{
public void run(){
while(true){
//your logic
if(stopThread)
break;
}
}
#Override
protected void onDestroy()
{
stopThread=true;
}

Android Inception (A thread within a thread)

I have one function which queries a network server with a few "ping pongs" back and forth, and have written a custom handler to handle the message communication between my main UI thread and the communication thread (I was using AsyncTask for this, but as the program got more complex, I have decided to remove the communication code to its own class outside of the main activity).
Triggering a single instance of this thread communication from onCreate works perfectly, no problem.
I want this query to run on a regular timed basis -- in the background -- for the entire time the app is in use, so I've set up another thread called pollTimer, which I'm trying to use to call the OTHER thread at a regularly scheduled basis.
Obviously, it's crashing, or I wouldn't be posting this.
Is there a way to get a thread within a thread? Or put differently, trigger a thread from another thread?
Timer pollTimer = new Timer();
private void startPollTimer(){
pollTimer.scheduleAtFixedRate(new TimerTask(){
public void run(){
Log.d(TAG,"timer dinged");
//if the following is commented out, this "dings" every 6 seconds.
//if its not commented out, it crashes
threadedPoll();
}
}, 3120, 6000);
}
private void threadedPoll() {
testThread(asciiQueries,WorkerThreadRunnable.typeLogin);
}
edit: it would probably help to include the "testThread" function, which works by itself when called from onCreate, but does not make it when called from the Timer.
"WorkerThreadRunnable" is the massive chunk of code in its own class that has replaced the mess of having AsyncTask handle it inside the main activity.
private Handler runStatHandler = null;
Thread workerThread = null;
private void testThread(String[] threadCommands, int commandType){
if(runStatHandler == null){
runStatHandler = new ReportStatusHandler(this);
if(commandType == WorkerThreadRunnable.typeLogin){
workerThread = new Thread(new WorkerThreadRunnable(runStatHandler,threadCommands, WorkerThreadRunnable.typeLogin));
}
workerThread.start();
return;
}
//thread is already there
if(workerThread.getState() != Thread.State.TERMINATED){
Log.d(TAG,"thread is new or alive, but not terminated");
}else{
Log.d(TAG, "thread is likely deaad, starting now");
//there's no way to resurrect a dead thread
workerThread = new Thread(new WorkerThreadRunnable(runStatHandler));
workerThread.start();
}
}
You seem to be well on the way already - the nice thing about handlers, though, is that they aren't limited to the UI thread - so if you have a Handler declared by one thread, you can set it up to take asynchronous instructions from another thread
mWorkerThread = new WorkerThread()
private class WorkerThread extends Thread {
private Handler mHandler;
#Override
public void run() {
mHandler = new Handler(); // we do this here to ensure that
// the handler runs on this thread
}
public void doStuff() {
mHandler.post(new Runnable() {
#Override
public void run() {
// do stuff asynchronously
}
}
}
}
Hopefully that helps... if I'm totally off base on your problem let me know
Wots wrong with a sleep() loop? Why do you have pagefuls of complex, dodgy code when you could just loop in one thread?

How to stop or destroy a running Thread

I have one thread class which star in onCreate of an activity.
class MyThread extends Thread
{
void run()
{
//My code which takes time.
}
}
//-------------------------- To run the thread
MyThread mThread = new MyThread();
mThread.start();
On some external events i need to stop/destroy currently running thread.
And Then i create a new copy of MyThread and call start function on the new thread to run it.
But i am not able to destroy/stop the previous running thread.
Is there any API by which we can destroy running thread.
you cannot destroy...only the android will stop the thread when requires.. you cannot stop or destroy it.. instead try like this..
class MyThread extends Thread
{
void run()
{
while(bool){
//My code which takes time.
}
}
}
//-------------------------- To run the thread
MyThread mThread = new MyThread();
mThread.start();
now when u want to stop the thread... change bool value to false
bool=false;
now your code doesnt run... and you can start new thread...
The Thread.interrupt() method is the accepted way of stopping a running thread, but some implementation details are on you: if your thread is doing IO (or anything else that can throw InterruptedException), it's your responsibility to make sure that you close any resources you have open before you stop your thread.
This page indicates why some of the thread functionality present in earlier versions of Java was deprecated, and why Thread.destroy() was never actually implemented.
You can use AsyncTask insted of Thread, because its known as Painless Threading in android. Once you implement you don't need to bother about Thread Management.
AsyncTask can easily handle and it's very easy for handling ui.
Instead of using Thread.interrupt() or any other methods that can throw an exception, you can implement your own stopThread method. In order to do that, you must have a local boolean variable with the name " keepRunning " for example.
If you have a for loop or a while loop inside your working code that takes time, you can check for the boolean, if it's false you break the loop and your code won't be running anymore.
class MyThread extends Thread
{
boolean keepRunning = true;
void run()
{
//inside your for loop
if (keepRunning) {
//keep running code which takes time.
}
else break;
}
void stopThread() {
keepRunning = false;
}
}
//To run the thread
MyThread mThread = new MyThread();
mThread.start();
//To stop the thread
mThread.stopThread();
After stopping the thread, you can initialize it again to mThread.
Try something like this..
class MyThread extends Thread
{
void run()
{
//My code which takes time.
}
}
//-------------------------- To run the thread
MyThread mThread = new MyThread();
mThread.start();
// PERFORM ALL YOUR OPERATIONS HERE..
mThread.destroy();

Categories

Resources