how to stop infinite loop threads from android service? - android

i am working with threads in sample application.In my application i have used 3 threads are running in infinite loop.These 3 threads are used in android service class.when i am starting these threads then the threads are running and UI is not allowing until completion of infinite loop.but how can i stop the threads and how can i handle UI?
i have written a service class as follows:
ServiceApp.java
public class ServiceApp extends Service
{
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
while(true)
{
Thread child1=new Thread(new Runnable() {
#Override
public void run() {
try {
function1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
child1.start();
Thread child2=new Thread(new Runnable() {
#Override
public void run() {
try {
function2();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
});
child2.start();
Thread child3=new Thread(new Runnable() {
#Override
public void run() {
try {
function3();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
child3.start();
Toast.makeText(ServiceApp.this, "All threads started", Toast.LENGTH_SHORT).show();
}
}
public void function1() throws InterruptedException
{
Generic generic=new Generic(); //this for connect to web services
String add=generic.getAdd(10,20);
Log.v("function1", "addition from service"+add);
Thread.sleep(1000);
}
public void function2() throws InterruptedException
{
Generic generic=new Generic(); //this for connect to web services
String sub=generic.getSub(34,20);
Log.v("function2", "subtraction from service"+sub);
Thread.sleep(1000);
}
public void function3() throws InterruptedException
{
Generic generic=new Generic(); //this for connect to web services
String mul=generic.getMul(4, 6);
Log.v("function3", "multipicationn from service"+mul);
Thread.sleep(1000);
}
}
how can i stop child1,child2,child3 threads from activity class?
please any body help me?

Service.onCreate() is executed inside the UI thread. You have an infinite loop there, that continuously creates more and more threads, so UI doesn't get a chance to respond to user's actions. If you actually intend to have so many threads, you need to create another thread that would start the original three.
Activity can communicate with the service either via Binder (you'll need to return an actual implementation instead of null there) or by sending intents, which you can capture and process in Service.onStart()

Related

running a method continously using the thread

I have a method which contains volley network library which will send some data to php server and fetch based on the value sent. I want to run this method continuously. I have created a Thread in the Oncreate method like below.
new Thread(){
#Override
public void run(){
second.this.runOnUiThread(new Runnable(){
#Override
public void run(){
try {
getNumber(second.this.getContentResolver());
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
}.start();
But i am not sure whether it is working. how can i check it is working or any mistake is there on implementation?

how to force the AsyncTask to wait

i want the AsyncTask to wait till it finishes. so i wrote the below code and i used .get() method as follows and as shown below in the code
mATDisableBT = new ATDisableBT();
but at run time the .get() doesnt force ATDisableBT to wait, becuase in the logcat i receive mixed order of messages issued from ATDisableBT and ATEnableBT
which means .get() on ATDisableBT did not force it to wait
how to force the AsyncTask to wait
code:
//preparatory step 1
if (this.mBTAdapter.isEnabled()) {
mATDisableBT = new ATDisableBT();
try {
mATDisableBT.execute().get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
//enable BT.
this.mATEnableBT = new ATEnableBT();
this.mATEnableBT.execute();
You can do this way:
doInBackground of AsyncTask
#Override
protected Void doInBackground(String... params) {
Log.i("doInBackground", "1");
synchronized (this) {
try {
mAsyncTask.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Log.i("doInBackground", "2");
return null;
}
Outside this function from where you have to nstrong textotify AsyncTask to release from wait state:
new CountDownTimer(2000, 2000) {
#Override
public void onTick(long l) {
}
#Override
public void onFinish() {
synchronized (mAsyncTask) {
mAsyncTask.notify();
}
}
}.start();
Here I have notified AsyncTask by CountDownTimer after 2 seconds.
Hope this will help you.
You should execute AsyncTask on UI thread, so using get() - which will block it makes no sense - it might get you ANR error.
If you are on HONEYCOMB and up, then AsyncTasks are executed on single executor thread, serially - so your mATEnableBT should get executed after mATDisableBT. For more see here:
http://developer.android.com/reference/android/os/AsyncTask.html#execute(Params...)
You might also switch from AsyncTask to Executors. AsyncTask is implemented using executors. By creating single threaded executor you make sure tasks will get executed serially:
ExecutorService executor = Executors.newSingleThreadExecutor();
//...
executor.submit(new Runnable() {
#Override
public void run() {
// your mATDisableBT code
}
});
executor.submit(new Runnable() {
#Override
public void run() {
// your mATEnableBT code
}
});

Stop thread in android application

public class CallEvent extends BroadcastReceiver{
public LEDController ledController = new LEDController();
public ApplicationSettings applicationSettings = new ApplicationSettings();
public boolean ring = false;
#Override
public void onReceive(Context context, Intent intent){
if(intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING)){
ring = true;
blink();
}else if(intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_IDLE) ||
intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_OFFHOOK)){
ring = false;
}
}
public void blink(){
Runnable r = new Runnable() {
#Override
public void run() {
while(ring){
ledController.turnOnFlash();
try {
Thread.sleep(applicationSettings.getDelayOn());
} catch (InterruptedException e) {
e.printStackTrace();
}
ledController.turnOffFlash();
try {
Thread.sleep(applicationSettings.getDelayOff());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
Thread blinkThread = new Thread(r);
blinkThread.start();
}
}
I want to create led messenger when phone is ring. But I can't stop blinkThread. I dont know it is not working. Led start when call income but don't stop when call decline. Variable ring is changing on 'false' when call decline, but thread still working
In general, you don't forcibly stop threads because it's dangerous. You set a flag that tells the thread in question to exit from it's thread loop under controlled circumstances.
Your thread loop looks something along these lines:
void run() {
while (shouldContinue) {
doThreadWorkUnit();
}
}
And somewhere else you set the shouldContinue variable and wait for the thread to finish:
...
thread.shouldContinue = false;
thread.join();
...
(All this is likely not correct Java, since I don't do Java. View it as pseudo code and modify for your actual language/thread library/etc.)
Source: How to stop a thread?

While Loop inside Thread not working?

I have a very simple UI and i need to constantly run a check process, so I am trying to use a Thread with a while loop.
When I run the loop with nothing but a Thread.sleep(1000) command, it works fine, but as soon as I put in a display.setText(), the program runs for a second on the emulator then quits. I cannot even see the error message since it exits so fast.
I then took the display.setText() command outside the thread and just put it directly inside onCreate, and it works fine (so there is no problem with the actual command).
here is my code, and help will be greatly appreciated.
Thank you!
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
on=(Button) findViewById(R.id.bon);
off=(Button) findViewById(R.id.boff);
display=(TextView) findViewById(R.id.tvdisplay);
display2=(TextView) findViewById(R.id.tvdisplay2);
display3=(TextView) findViewById(R.id.tvdisplay3);
stopper=(Button) findViewById(R.id.stops);
stopper.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(boo=true)
{
boo=false;
display3.setText("System Off");
}
else{
boo=true;
}
}
});
Thread x = new Thread() {
public void run() {
while (boo) {
display3.setText("System On");
try {
// do something here
//display3.setText("System On");
Log.d(TAG, "local Thread sleeping");
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.e(TAG, "local Thread error", e);
}
}
}
};
display3.setText("System On");
display3.setText("System On");
x.start();
}
You can't update the UI from a non-UI thread. Use a Handler. Something like this could work:
// inside onCreate:
final Handler handler = new Handler();
final Runnable updater = new Runnable() {
public void run() {
display3.setText("System On");
}
};
Thread x = new Thread() {
public void run() {
while (boo) {
handler.invokeLater(updater);
try {
// do something here
//display3.setText("System On");
Log.d(TAG, "local Thread sleeping");
Thread.sleep(1000);
} catch (InterruptedException e) {
Log.e(TAG, "local Thread error", e);
}
}
}
};
You could also avoid a Handler for this simple case and just use
while (boo) {
runOnUiThread(updater);
// ...
Alternatively, you could use an AsyncTask instead of your own Thread class and override the onProgressUpdate method.
Not 100% certain, but I think it is a case of not being able to modify UI controls from a thread that did not create them?
When you are not in your UI thread, instead of display3.setText("test") use:
display3.post(new Runnable() {
public void run() {
display3.setText("test");
{
});
You should encapsulate this code in an AsyncTask instead. Like so:
private class MyTask extends AsyncTask<Void, Void, Void> {
private Activity activity;
MyTask(Activity activity){
this.activity = activity;
}
protected Long doInBackground() {
while (true){
activity.runOnUiThread(new Runnable(){
public void run(){
display3.setText("System On");
}
});
try{
Thread.sleep(1000);
}catch (InterruptedException e) {
Log.e(TAG, "local Thread error", e);
}
}
}
Then just launch the task from your onCreate method.
In non-UI thread,you can't update UI.In new Thread,you can use some methods to notice to update UI.
use Handler
use AsyncTask
use LocalBroadcast
if the process is the observer pattern,can use RxJava

how to use notify and wait

Can wait/notify be used within one thread?
I'm mean I have a listener and in the moment when that listener gets called I wanna enable a thread to do his work.How could I do that?
UPDATE:My data is written in a database...and is written each time the listener is called.Now the thread that I've created reads that data and sends it somewhere....
Next...I get some other data and do the same thing....The other thread needs to know what was the last data he read it so he can start reading from where he left....
Take a look in here:
using wait and notify within one thread
This is how my problem looks like.Thx
I have the following:
synchronized (syncToken)
{
try {
syncToken.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("MyThread: " + s);
in MyThread....so when I do
MyThread t = new MyThread(syncToken);
t.start();
I put my thread on waiting...yes?
And when I do this:
syncToken.notify();
I get my thread back on track....but the execution of the next line is the one after wait()?
I mean this: System.out.println("MyThread: " + s); ????
When u notify a thred does he continues his execution with the line after wait()???Thx
The following is a simple example of concurrency between two different threads. In the example the main thread start a MyThread thread and every 3 seconds it sets a data to the MyThread instance and then MyThread prints it. The idea is to have a synchronized object that you wait on it and notify in the end of the usage to other threads that they can use it:
Test.java:
package stack;
public class Test {
public static void main (String args[])
{
Object syncToken = new Object();
MyThread t = new MyThread(syncToken);
t.start();
for (int i = 0; i < 10; i++)
{
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(syncToken)
{
t.setText("Iteration " + i);
syncToken.notify();
}
}
}
}
MyThread.java:
package stack;
public class MyThread extends Thread{
String s;
Object syncToken;
public MyThread(Object syncToken)
{
this.s = "";
this.syncToken = syncToken;
}
public void run()
{
while(true) // you will need to set some condition if you want to stop the thread in a certain time...
{
synchronized (syncToken)
{
try {
syncToken.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("MyThread: " + s);
}
}
public void setText(String s)
{
this.s = s;
}
}
In this example, the main thread sets a string (every 3 seconds) and the MyThread thread prints it.
Adapt it to your needs, it shouldn't be too hard.
I had similar problem. I created an arbiter used by two threads (in your case it can be listeners thread and your task thread):
listener:
arbiter.waitConsumer();
// prepare data
arbiter.dataLoaded();
task thread:
while(true){
arbiter.waitProducer();
// consume data
arbiter.dataConsumed();
}
arbiter:
public class Arbiter {
private boolean dataLoaded = false;
public synchronized void waitProducer(){
while(!dataLoaded){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void waitConsumer(){
while(dataLoaded){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void dataLoaded(){
dataLoaded = true;
notify();
}public synchronized void dataConsumed(){
dataLoaded = false;
notify();
}}
Listener and task will synchronize themselfes against arbiters monitor. Probably you can call your arbiter queue or pipe and store date for consuming in it?

Categories

Resources