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?
Related
i am trying to display a Toast on the screen and when Toast fades off then move to the next question. I have tried with Thread but cannot seem to manage.
My code:
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (getUserSelection()){
position = position + 3;
if (position < questionsArray.size()) {
curName = questionsArray.get(position).getName();
curArray = questionsArray.get(position).getAnswers();
curIscorrect = questionsArray.get(position).getIscorrect();
setupQuestionView(curName, curArray, curIscorrect);
} else {
StringGenerator.showToast(QuestionsActivity.this, "Your score : " + score + "/" + (questionsArray.size() / 3));
}
}else {
StringGenerator.showToast(QuestionsActivity.this, getString(R.string.noanswerselected));
}
}
});
and the getUserSelectionMethod:
private boolean getUserSelection() {
correct = (RadioButton)findViewById(group.getCheckedRadioButtonId());
if (correct == null){
return false;
}else {
correctAnswerText = correct.getText().toString();
if (map.get(correctAnswerText).equals(Constants.CORRECTANSWER)) {
score++;
setCorrectMessage();
return true;
} else {
setWrongMessage();
return true;
}
}
}
private void setCorrectMessage() {
correctToast = new Toast(QuestionsActivity.this);
correctToastView = getLayoutInflater().inflate(R.layout.correct, (ViewGroup) findViewById(R.id.correctRootLayout));
correctText = (TextView)correctToastView.findViewById(R.id.correctTextView);
correctText.setText(getString(R.string.correctAnswer));
correctToast.setDuration(Toast.LENGTH_SHORT);
correctToast.setView(correctToastView);
correctToast.show();
correctThread = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
correctToast.cancel();
}
});
correctThread.start();
}
private void setWrongMessage() {
wrongToast = new Toast(QuestionsActivity.this);
wrongToastView = getLayoutInflater().inflate(R.layout.wrong, (ViewGroup) findViewById(R.id.wrongRootLayout));
wrongText = (TextView)wrongToastView.findViewById(R.id.wrongTextView);
wrongText.setText(getString(R.string.wrongAnswer));
wrongToast.setDuration(Toast.LENGTH_SHORT);
wrongToast.setView(wrongToastView);
wrongToast.show();
wrongThread = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
wrongToast.cancel();
}
});
wrongThread.start();
}
Any suggestion on how to do this?
You can determine the toast visibility:
toast.getView().getWindowToken()
If the result is null, than your toast isn't visible anymore, and than you can run any code you want.
as stated in this answer you can start a thread that waits the duration of the Toast:
Thread thread = new Thread(){
#Override
public void run() {
try {
Thread.sleep(3500); // 3.5seconds!
// Do the stuff you want to be done after the Toast disappeared
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Toast.LENGTH_SHORT and Toast.LENGTH_LONG are only flags so you have to either hard code the duration or keep them in a constant. The durations are 3.5s (long) and 2s (short).
If you want to manipulate some of your views, you cannot do this in another thread than the "main" UI thread. So you have to implement a kind of callback/polling mechanism to get notified when the SleepThread has finished.
Check this answer to read about a couple of ways to do this. Probably the easiest of them to understand and implement is this:
After you started your Thread you can check if it is still alive and running by calling thread.isAlive(). In this way you can do a while loop that runs while the thread is running:
// start your thread
while(thread.isAlive()){}
// continue the work. The other thread has finished.
Please note that this is NOT the most elegant way to do this! Check the other possibilities in the answer I've mentioned above for more elegant solutions (especially the last one with the listeners is very interesting and worth reading!)
That's because the Thread class is purely executed in the background and you need to manipulate the view in the Main thread. To solve your issue just replace the Thread with AsynTask.
AsyncTask<Void,Void,Void> a = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
correctToast.cancel();
}
};
a.execute();
If you look at my code you can see my onPostExecute, this method is called in the Main Thread.
My Error was because i was trying to acess UI Elements through another Thread so modifying the code like this:
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(500);
QuestionsActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
moveToNextQuestion();
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
thread.start();
did the trick. I hope my answer helps someone!!!
I have implemeted a custom camera and I want it to go, after a period of time into a standby state. The standby concsists from a stopPreview, a camera release and a view that tells the user to tap in order to exit the standby. Because I set the text within the new thread, I get the CalledFromWrongThreadException, but I don't know what the solution could be. I found other posts around, but none of them really worked.
Code:
private void initCamera()
{//more code
threadModifiedText = (TextView) findViewById(R.id.textView1);
Thread standbyThread = new Thread()
{
#Override
public void run()
{
try
{
while (timeCounter > 0)
{
if (!activeThread)
{
sleep(100);
if (timeCounter % 10 == 0)
{
threadHandler.sendEmptyMessage((int) timeCounter / 10);
}
timeCounter--;
}
}
}
catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.stopPreview();
mCamera.release();
TextView standbytext = new TextView(SlicesActivity.this);
standbytext.setText("Tap to exit standby mode");
FrameLayout preview = (FrameLayout) findViewById(id.FrameLayout_camera_preview);
preview.addView(standbytext);
}
};
standbyThread.start();
//more code}
And
#Override
public void onUserInteraction()
{
Log.d("~~~~~~~~~", "apasat");
activeThread = true;
timerCounter = 300;
}
private Handler threadHandler = new Handler()
{
public void handleMessage(android.os.Message msg)
{
// whenever the Thread notifies this handler we have
// only this behavior
threadModifiedText.setText("\ncounter is " + Integer.toString(msg.what));
}
};
Please guys, give me some suggestions. 10x
try to use
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO: update your UI here
}
});
in your thread to update UI
You cannot set text values inside any thread except the UI thread. Complete your background thread operations and set the text value after your operations are over in the UI thread.
This is a common question, and I have read up on the various ways of handling it, but each on seems to fall short for what I am trying to do, which is essentially be a good OO-Citizen.
I have an Activity that invokes a CommunicationManager, which basically polls a TCP socket for data. When the CommunicationManager receives data, it throws a custom event (containing the string it just fetched), which is handled by the Activity. I am doing this, A) because other classes will depend on that data, not just the Activity, and B) because the polling is asynchronous, and should fire an event when it receives results.
My problem lies in that I need to surface those results into a TextView on the UI. I have the polling mechanism all set up, it fires every 1000ms, and invokes the event handler on the Activity. However, the UI never updates.
Assumedly this is a thread issue and the UI thread is not the one getting the change to the TextView, but how do I do this?? I have tried using a Handler, but am not sure where to put it, and when I did get it compiling it never updated the UI.
This seems relatively trivial if everything was done within the Activity, but adding in this other class (CommunicationManager) and the event is making it very confusing for me.
Here is what I have so far:
ACTIVITY (polling is invoked by clicking a button on the UI):
public void onClick(View v) {
if (v.getId() == R.id.testUDPBtn) {
statusText.setText("");
commMgr = new CommunicationManager();
commMgr.addEventListener(this);
MediaPositionPollThread poller = new MediaPositionPollThread(commMgr);
poller.startPolling();
}
}
#Override
public void handleMediaPositionFoundEvent(MediaPositionFoundEvent e) {
statusText.append(e.userData);
}
THREAD:
class MediaPositionPollThread extends Thread {
private CommunicationManager commManager;
private static final String TAG = "MediaPositionPollThread";
private boolean isPolling = false;
public MediaPositionPollThread(CommunicationManager cm) {
commManager = cm;
}
public void startPolling() {
isPolling = true;
this.run();
}
public void stopPolling() {
isPolling = false;
}
#Override
public void run() {
while (isPolling) {
try {
commManager.getCurrentMediaPosition();
Thread.sleep(1000);
}
catch (InterruptedException e) {
Log.d(TAG, "EXCEPTION: " + e.getMessage());
}
}
}
}
COMMUNUCATION MANAGER:
public void getCurrentMediaPosition() {
PrintWriter outStream;
BufferedReader inStream;
String resultString = "";
try {
outStream = new PrintWriter(tcpSocket.getOutputStream(), true);
outStream.println("GET?current_pts");
inStream = new BufferedReader(new InputStreamReader(tcpSocket.getInputStream()));
resultString = inStream.readLine();
fireEventWithData(resultString);
} catch (Exception e) {
e.printStackTrace();
}
}
public synchronized void addEventListener(MediaPositionFoundEventListener listener) {
_listeners.add(listener);
}
public synchronized void removeEventListener(MediaPositionFoundEventListener listener) {
_listeners.remove(listener);
}
private synchronized void fireEventWithData(String outputString) {
MediaPositionFoundEvent evt = new MediaPositionFoundEvent(this);
evt.userData = outputString;
Iterator<MediaPositionFoundEventListener> i = _listeners.iterator();
while(i.hasNext()) {
((MediaPositionFoundEventListener) i.next()).handleMediaPositionFoundEvent(evt);
}
}
So I have the Activity making a thread that gets executed every second, calling CommunicationManager >> getCurrentMediaPosition, which in turn fires the MediaPositionFoundEvent, which is handled by the Activity and updates the TextView (statusText) on the screen.
Everything works except the screen not updating. I have tried runOnUiThread, and a Handler, but am obviously not getting it right.
Thanks in advance for any insight or solutions!
In your Activity class, add a private Handler _handler,
Initialize it in your onCreate Activity method,
and change your handleMediaPositionFoundEvent method to
#Override public void handleMediaPositionFoundEvent(MediaPositionFoundEvent e) {
_handler.post(new Runnable(){
public void run(){
statusText.append(e.userData);
});
}
}
It looks like your blocking the UI thread with your custom Thread. Please update this method to call start() vs run().
public void startPolling() {
isPolling = true;
this.start();
}
hi i am working on custom toast , and i am able to do that, but after when i move to next activity the thread is running or active of back activity , so what should i do for removing that thread or stop this thread.
my code is given below :
public void customToast(int x, int y, String str) {
if (Util.tipson == true) {
toast = new Toast(getApplicationContext());
toast.setDuration(Toast.LENGTH_SHORT);
toast.setGravity(Gravity.TOP, x, y);
LayoutInflater li = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
toastView = li.inflate(R.layout.toastlayout, null);
toast.setView(toastView);
TextView text = (TextView) toastView.findViewById(R.id.text);
text.setText(str);
// toast.show();
fireLongToast();
}
}
private void fireLongToast() {
t = new Thread() {
public void run() {
int count = 0;
try {
while (true && count < 40) {
try {
toast.show();
sleep(100);
count++;
} catch (Exception e) {
// TODO: handle exception
}
// do some logic that breaks out of the while loop
}
toast = null;
toastView = null;
} catch (Exception e) {
Log.e("LongToast", "", e);
}
}
};
t.start();
}
You Need to stop your thread by yourself. Since java doesn't allow you to use stop() function.
Write class for your Thread as this
public class YourThread extends Thread {
private volatile boolean stopped = false;
public void run() {
int count = 0;
try {
while (true && count < 40 && !stopped) {
try {
toast.show();
sleep(100);
count++;
} catch (Exception e) {
// TODO: handle exception
}
// do some logic that breaks out of the while loop
}
toast = null;
toastView = null;
} catch (Exception e) {
Log.e("LongToast", "", e);
}
}
public void stopThread() {
stopped = true;
}
}
Now when your Activity which has the Thread Finishes stop Your thread
#Override
protected void onDestroy() {
if(isFinishing())
yourThreadVariable.stopThread();
}
Dont know for sure, but you can call the function join of thread in onDestroy of your activity.
To stop the thread you can just use interrupt(). But for better solution I would say not to use Thread. Just create a Handler with Runnable and manage your Runnable using Handler, that would be a nice way as Android has given Handler for managing one or more Runnables.
Creating a Runnable
Runnable runnable = new Runnable() {
#Override
public void run() {
// put your code stuff here
}
};
To start Runnable use
handler.postDelayed(runnable, your_time_in_millis);
To stop Runnable use
handler.removeCallbacks(runnable);
Does finishing the activity have any effect?
I would like to suggest Lalit Poptani method too and implement this:
protected void onStop(){
handler.removeCallbacks(runnable);
super.onStop();
}
The documentation for the method:
onStop,Called when the activity is no longer visible to the user, because another activity has been resumed and is covering this one. This may happen either because a new activity is being started, an existing one is being brought in front of this one, or this one is being destroyed.
http://developer.android.com/reference/android/app/Activity.html
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?