I'm starting a thread like this in my app.
private void AppThreadWorker()
{
AppThread = new Thread(new Runnable() {
#Override
public void run() {
while (canRun)
{
//do async get from server
}
});
AppThread.start();
}
I want to be able to move this app in background and I want this thread continues working. This works fine. The problem is that after 1 hour the Thread stops. Do you know some tricks to let him run for more time?
Use Service for This.
Create a Thread inside Service because by default Service run in UI (Main) Thread.
Related
I'm using Android Studio and emulator android 4.1.2.
My code
Timer timer = new Timer ();
timer.schedule(new TimerTask() {
#Override
public void run() {
myRun();
}
},10000,10000);
result in "unfortunately, app has stopped", however I found out the code
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
myRun();
}
}, 2000);
runs ok and displays as I expect.
What is the inner difference between the two?
P.S.
public void myRun () {
myView.removeAllViews();
drawView = new DrawView(myContext, myView);
myView.addView(drawView);
}
I'm trying to perpetually update a custom view until user cancels it. Just cycle
while (myRun) {
results in emulator becoming unresponsive to even back button, running that update in second thread
new Thread(new Runnable() {
#Override
public void run() {
while (myRun) {
myView.post(new Runnable() {
public void run() {
myView.removeAllViews();
drawView = new DrawView(myContext, myView);
myView.addView(drawView);
}
});
}
}
}).start();
results in same (interestingly to me, if I run debug with breakpoint on while in second thread, screen updates as I expect many times, however running w/out debugging does not update screen).
Timer executes its tasks on a separate thread that is used only for serving tasks created by this particular timer. Handler runs its task on its Looper's thread which may or may not be a UI thread. Generally speaking there's no much difference between this two classes if you use Handler on a separate thread. But it's more common in Android to use Handler and HandlerThread.
If you need to interact with UI, you'd better use Handler.
This is an interesting question and answer lies in Thread/GUI policy that android follows.
As we know, UI runs on main thread. Timer creates a different thread and android does not allow to update UI in a different thread. Why?
Suppose, you have started a thread in your activity that updates a TextView and while the thread is running you move to some other app. Now, main thread no longer exists and when the other thread tries to update the TextView it is not able to find that TextView. As a result, we see a crash.
Now let me come to the difference between TimerTask and Handler.
TimerTask creates a new thread, waits for the time specified and then executes run() method in the same thread. On the other hand, Handler creates a new thread, waits for specified duration then returns to main thread and executes run() method on MAIN thread(if handler is on main thread). Hence, it works fine.
However you can do it with timer too.
See the code below:
final Runnable setRunnable = new Runnable() {
public void run() {
myView.removeAllViews();
drawView = new DrawView(myContext, myView);
myView.addView(drawView);
}
};
TimerTask task = new TimerTask(){
public void run() {
getActivity().runOnUiThread(setRunnable);
}
};
Timer timer = new Timer();
timer.schedule(task, 1000);
In this thread you are setting a runnable to run on UI thread after timer's duration.
I've been writing android apps for some months now, and I'm at the point where I'm building an actual needed app.
As I want that to work nice and fast, I made a Workerthread to do all kinds of tasks in the background while the UI can...build up and work and stuff.
It's based on the Android Studio Drawer app blueprint.
In Main.onCreate I got my operator=new Operator(), which extends Thread.
Now, when loading a new Fragment, it sometimes calls MainActivity.operator.someMethod() (I made operator static so I can use it from anywhere), and after some time I realized, the only tasks actually running in background are those in the operators run() method and an Asynctask my login Fragment runs. Everything else the UI waits for to complete and therefore gets executed by the UI thread.
So I thought: no problem! My operator gets a handler which is built in run(), and I change those tasks:
public void run() {
Looper.prepare(); //Android crashed and said I had to call this
OpHandler = new Handler();
LoadLoginData();
[...Load up some Arrays with hardcoded stuff and compute for later use...]
}
public void LoadLoginData() {
OpHandler.post(LoadLoginDataRunnable);
}
private Runnable LoadLoginDataRunnable = new Runnable() {
#Override
public void run() {
if(sharedPreferences==null)
sharedPreferences= PreferenceManager.getDefaultSharedPreferences(context);
sessionID=sharedPreferences.getString("sessionID", null);
if(sessionID!=null) {
postenID = sharedPreferences.getString("postenID", PID_STANDARD);
postenName = sharedPreferences.getString("postenName", PID_STANDARD);
context.QuickToast(sessionID, postenName, postenID);
}
}
};
context is my MainActivity, I gave the operator a reference so I could send Toasts for Debugging.
But now, the Runnables seem to not run or complete, any Log.e or Log.d stuff doesn't arrive in the console.
After some googeling and stackoverflowing, everyone is just always explaining what the difference is between Handlers, Asynctask, and Threads. And the multitask examples always only show something like new Thread(new Runnable{run(task1)}).start times 3 with different tasks.
And so became my big question:
How to correctly, over a longer time (~lifecycle of the MainActivity), with different tasks, use a background thread?
Edit: to clarify, I would also like a direct solution to my special problem.
Edit 2: after reading nikis comment (thank you), the simple answer seems to be "use HandlerThread instead of thread". Will try that as soon as I get home.
Trying a HandlerThread now. It seems my OpHandler, initialized in run(), gets destroyed or something after run() has finished, not sure whats up here (this is btw another mystery of the kind I hoped would get answered here). I get a NullpointerException as soon as I try to use it after run() has finished.
Make your worker thread own a queue of tasks. In the run() method, just pop a task from the queue and execute it. If the queue is empty, wait for it to fill.
class Operator extends Thread
{
private Deque<Runnable> tasks;
private boolean hasToStop=false;
void run()
{
boolean stop=false;
while(!stop)
{
sychronized(this)
{
stop=hasToStop;
}
Runnable task=null;
synchronized(tasks)
{
if(!tasks.isEmpty())
task=tasks.poll();
}
if(task!=null)
task.run();
}
}
void addTask(Runnable task)
{
synchronized(tasks)
{
tasks.add(task);
}
}
public synchronized void stop()
{
hasToStop=true;
}
}
I'm working on an app that synchronizes some graphic UI events with an audio track. Right now you need to press a button to set everything in motion, after onCreate exits. I'm trying to add functionality to make the audio/graphical interaction start 10 seconds after everything is laid out.
My first thought is, at the end of onCreate, to make the UI thread sleep for 10000 miliseconds using the solution here and then to call button.onClick(). That seems like really bad practice to me, though, and nothing came of trying it anyway. Is there a good way to implement this autostart feature?
Never ever put sleep/delay on UI-thread. Instead, use Handler and its postDelayed method to get it done inside onCreate, onStart or onResume of your Activity. For example:
#Override
protected void onResume() {
super.onResume();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
//do whatever you want here
}
}, 10000L); //the runnable is executed on UI-thread after 10 seconds of delay
}
Handler handler=new Handler();
Runnable notification = new Runnable()
{
#Override
public void run()
{
//post your code............
}
};
handler.postDelayed(notification,10000);
Yes, putting the UI thread to sleep isnt a good idea.
Try this
private final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
worker.schedule(task, 10, TimeUnit.SECONDS);
I've basically done this but my when I run the app, it runs the thread too many times too quickly before freezing.
Looking to have my thread run through once, pause and then start the thread again.
I have tried:
while (running.get()) {
Thread threadstart = new Thread()
{
public void run(){
try {
Thread.sleep(integerTime);
and then had
threadstart.start();
at the end. This is my exact code just with all the processes taken out.
All advice appreciated.
You're sleeping in the new thread - so your while loop will keep spawning new threads at a very fast rate, each of which will sleep.
Why not just create one thread which has the loop?
Thread thread = new Thread(new Runnable() {
#Override public void run() {
while (running.get()) {
try {
Thread.sleep(integerTime);
// Do work
}
}
}
};
thread.start();
hi all
since i am using a button and on the click of that button it connects to a Web Service.
But the problem is that when i press the button it does not showed me that it has been clicked and goes to connect to the internet and web service. after connecting it shows me the response that it has been clicked. in short the response of button is very slow. if that buton has some INternet connectvity in its Listener.
i know it has something to do with UI thread. but please friends guide me through this.
Thanks a bunch,
Put the following code in your class:
// Need handler for callbacks to UI Threads
// For background operations
final Handler mHandler = new Handler();
// Create Runnable for posting results
final Runnable mUpdateResults = new Runnable() {
public void run() {
// Do your task which needs to get done after webservice call is complete.
}
};
And for calling the webservice use the following code in button event:
new Thread() {
public void run() {
// Place the webservice call here.
mHandler.post(mUpdateResults);
}
}.start();
Actually what are you looking for is multithreading, all the webservice calls and network activities should go in separate thread.
After the thread start() call you can do what ever you want and would be done instantly without any delay (in your case showing that button pressed).
You have to use Handler for this background operation already ask on OS follow this link
progress dialog not showing in android?
You should write a class say MyWebService and extend it from AsyncTask. Perform the connect operation in its overridden doInBackground() method and update any UI changes in its onPostExecute() method.
Create a new Thread in the onClickListener that does the heavy work in the background. That way the UI thread will be able to update the state of the button:
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
new Thread(new Runnable() {
#Override
public void run() {
// Code that connects to web service goes here...
}
}).start();
});