How to Control Multiple threads of Same Object? - java

following is inside my button click in android
protected onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState)
public void onClick(View arg0)
{
if(connectThread!=null)
{
connectThread.kill();
}
connectThread=new ConnectThread(device);
connectThread.start();
}
}
I have made a boolean volatile variable running in ConnectThread class which is true by default and kill method will set it value to false.
Problem is that still it is not working the reason may be that in my ConnectThread run method im creating another thread but that should not be the problem since that gets called from the run method and since that will be child thread of ConnectThread; on killing connectThread that will automatically get cancelled?
kill method of ConnectThread
public void kill()
{
running=false;
}
run method of ConnectThread
public void run()
{
while(running)
{
}
}

If the app was still active on your device, and you started a second connection thread, the bluetooth device might not be available.
I recommend you read up on the Android Activity Lifecycle.

Related

Android - pause and continue thread

In my Activity I create a Thread for multiply objects and "save" them to a hashmap. Is it possible to pause just a single thread of the hasmap and continue it?
public void onCreate(Bundle savedInstanceState) {
Thread oThread = new Thread(new Runnable() {
public void run() {
while (true) {
// doing some work
}
}
}
oThread.start();
aThreads.put(name, oThread);
}
public void anyMethod(){
// here I want to start and continue a thread
aThreads.get(name).stop();
aThreads.get(name).resume();
}
But .stop() and .resume() aren't working :/ any suggestions?
Use a boolean variable to control the thread exection.
ie.
while(!isThreadRunning){
...your statements
}
Once you are moving out of the screen in OnPause method make the variable false/true based on your usage to stop the thread execution.And you have to take care of the persisting hashmap.

Android pause/resume AsynTask

I have a UI thread(MainActivity) calling an AsynTask object(DownloadManager), which, in turn calls 3 threads (DownloaderThread).
How do I pause/resume the 3 DownloaderThreads without pausing the AsynTask or the UI thread?
Following is the code I have currently implemented for the pause functionality, but when the Pause button is clicked, the app crashes with the dialog: "app has stopped". Code:
DownloadManager (AsynTask):
public void onPause() {
try{
t0.wait();
t1.wait();
t2.wait();
this.wait();
}catch (InterruptedException ex){
}
}
DownloaderThread (implements Runnable and is passed to a Thread instance in DownloadManager:
public class DownloaderThread implements Runnable {
private Object mPauseLock;
private Boolean mPaused;
private Boolean mFinished;
public void run(){
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
try{
while(!mFinished){
//do something
synchronized (mPauseLock){
while (mPaused){
try{
mPauseLock.wait();
}catch (InterruptedException e){
}
}
}
}
}
}
public void onPause(){
synchronized (mPauseLock){
mPaused = true;
}
}
You can't really pause an AsyncTask once it started. You can, however, store the progress when activity is paused/destroyed and start from the progress once you are back to the original Activity. But I recommend the best way to complete task for your scenario is to use Service.

Null pointer error due to thread not stopping before orientation change

I have a fragment that displays weather data that runs a background thread that essentially just calls a function in my main UI to check whether my forecast is still valid. This function updates the UI so I am using a Handler and posting a Runnable to the main thread, like so:
public class WaveFxListFragment extends Fragment implements
LoaderManager.LoaderCallbacks<Cursor>, View.OnClickListener {
// .....
// handler for dealing with synchronising update thread with UI
private Handler mHandler;
private UpdateThread mUpdateThread;
private class UpdateThread extends Thread {
volatile boolean running = false;
#Override
public void run() {
running = true;
while (running) {
// get main UI thread to perform update check:
Log.d(TAG, "Handler is " + mHandler);
mHandler.post(new Runnable() { // getting null pointer error here!
#Override
public void run() {
checkValidTime();
}
});
try {
Thread.sleep(1000); // sleep 1 second
} catch (InterruptedException e) {
Log.d(TAG, "Thread was interrupted!");
e.printStackTrace();
}
}
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Reuse existing handler:
mHandler = getActivity().getWindow().getDecorView().getHandler();
}
#Override
public void onResume() {
super.onResume();
// start update checker:
mUpdateThread = new UpdateThread();
mUpdateThread.start();
}
#Override
public void onPause() {
// stop update thread
Log.d(TAG, "Asking thread to stop");
mUpdateThread.running = false;
super.onPause();
}
}
This works fine; the problem is when I change my screen orientation. The current activity gets destroyed and if the thread is running, it tries to post a Runnable to a UI thread that no longer exists. So, I put a running member variable in the UpdateThread class and set if to false when my activity goes calls onPause. However, even though I have set the UpdateThread.running variable to false, my thread still tries to post a Runnable, but the Handler is now null! It shouldn't get that far, but it is!
Am I doing this wrong? My log message "Asking thread to stop" gets printed out, so I know it is getting as far as setting running to false.
Can anyone offer an insight?
Thanks
A few things that you can do to resolve this.
Interrupt the thread after you set running to false. This should cause the thread to exit earlier, or at the very least for your error to appear earlier.
Check that your handler is not null in your update thread, and set it to null in onPause.
Move the assignment of mHandler to onResume to make sure that mHandler is valid when the update thread is called.

Deprecated Thread methods are not supported without stop() method

I programmed game, which is supposed to use .startActivity on activity which should display score, the problem is, that instead of properly displaying the activity, i'm getting "Deprecated Thread methods are not supported". I googled this error and i removed all Thread.stop() in my application, but it did not helped. Could there be any other reason why i'm getting this type of error?
public class GameFrame extends Activity implements OnTouchListener, OnLossListener {
Panel game;
#Override
public void onCreate(Bundle savedInstanceState) {
Display d=getWindowManager().getDefaultDisplay();
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
Point p=new Point(d.getWidth(),d.getHeight());
game=new Panel(this,p);
setContentView(game);
game.setOnTouchListener(this);
game.setOnLossListener(this);
}
public boolean onKeyDown (int kc,KeyEvent ke){
if (kc==23){
game.shoot();
}
return true;
}
public void onPause(){
super.onPause();
game.thread.setState(false);
game.mech.setState(false);
this.finish();
}
#Override
public boolean onTouch(View v, MotionEvent me) {
if (v.equals(game)){
game.setPosOfPlane((int)me.getX());
}
return true;
}
#Override
public void lost(int score) {
Intent i=new Intent (this,EndGame.class);
i.putExtra("score",score+"");
startActivity (i);
}
}
Use Thread.currentThread().interrupt(); instead stop();
Hope it helps cya!
I can't tell you what exactly is the problem, but I can give you some hints.
First of all you usually create a thread when starting your application and let it run until you want to exit your game (user pressed BACK). Other than that you only pause your game thread, e.g. when you're displaying another activity or your app is temporarily suspended (user pressed HOME).
If you want to end your game thread, just let it die naturally. Usually such thread runs in some sort of a loop, so you just exit this loop and the thread will terminate on its own. You usually call join() on the game thread from the main thread to block it until the game thread dies.
You should never manipulate thread's state directly.

Taking heavy computation off the Android UI Thread

My Android app employs a particularly big computation which keeps crashing the system because it is on the UI thread in the Activity.
I have little confidence in multithreading and so I want to get some tips on how to do it correctly.
This is what I have
class ActivtyName extends Activity{
boolean threadcomplete = false;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//stuff
Runnable newthread = new Runnable(){
#Override
public void run() {
doBigComputation();
threadcomplete=true;
}
};
newthread.run();
boolean b = true;
while(b){
if(threadcomplete){
b=false;
startTheApp();
}
}
}
}
Now, I am pretty sure what I have done is not "correct". (It seems to work though. The sistem doesn't crash). Basically, I'm not sure how the UI thread can be told that newthread has finished the computation without this boolean, threadcomplete. Is there a "correct" way to do this?
Just to expand a bit on Marek Sebera's comment, here's the framework on how you would accomplish that in an AsyncTask.
private class BigComputationTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
// Runs on UI thread
Log.d(TAG, "About to start...");
}
#Override
protected Void doInBackground(Void... params) {
// Runs on the background thread
doBigComputation();
}
#Override
protected void onPostExecute(Void res) {
// Runs on the UI thread
Log.d(TAG, "Big computation finished");
startTheApp();
}
}
And to call it:
BigComputationTask t = new BigComputationTask();
t.execute();
In addition to Marvin's answer, there's a good article on the Android developer site about precisely this.
That's not the correct way to start a thread. You need to do:
Runnable newthread = new Runnable(){
#Override
public void run() {
doBigComputation();
threadcomplete=true;
}
};
Thread t = new Thread(newthread);
newthread.start();
boolean b = true;
while(b){
if(threadcomplete){
b=false;
startTheApp();
}
}
When i want to use threads, I've almost a big while loop. I put a boolean condition who's always true, except when I want to stop it.
I use Thread (http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html) and I reimplement the stop method because it's deprecated. So in my stop method I can put a false value to the loop variable.
To terminate the thread, I use t.stop(). So you can di that in your activity.
If you want to know when a Thead stops, you can use t.isAlive(). If the thread t is started, isAlive will return true.

Categories

Resources