I've been reading up on how to use Thread in java, and I'm hoping someone can help me verify I'm using it correctly. I'm concerned that I should be calling .interrupt() or destroying the thread in some way.
I have a simple script that just hits my server to verify some data. My code:
Thread checkregister = new Thread(){
#Override
public void run(){
checkSystem();
}
};
checkregister.start();
Where checkSystem() posts the device id to a php script and waits for the response via HttpClient & HttpResponse. There isn't any looping so I don't think blocking is called for, but please let me know if I'm wrong.
No need to destroy the Thread. The Thread is effectively taken out of the thread scheduler as soon as run() returns.
If for some reason you need a way to prematurely "end" the Thread, this is a bit more complicated and there's been a lot of discussion about the proper way to do it. Simple way though is to just call stop() on the Thread.
Related
I am making an android game which is made up of a game loop that is constantly running as well as use of the android UI stuff. So they need to be in separate threads to work concurrently.
I am planning to put the game loop inside an AsyncTask however it says in the developer.android documentation that
AsyncTasks should ideally be used for short operations (a few seconds at the most.)
My game loop will in theory be operating indefinitely and almost always for more than a few seconds. Is the asynctask the right place to put this then or is there another preferred method to split up a game loop and the UI operations
AsyncTasks are for short operations only, as the documentation has stated. Also, they usually do some work that shouldn't interfere with the UI. Hence, "Async" and "Task".
What you should use instead is a new Thread. This is called Multi-Threading. There are a lot of Game Frameworks out there which will have problems with android's UI. Though you have not stated what UI Operations you are talking about, but if you plan to use the android's widgets(UI), you could call Activity.runOnUiThread() to run a code on the UI Thread, for example, changing a TextView's text.
Here is a snippet on how you would create a never ending loop in a new thread(or something like this, i dont remember if the function is private):
new Thread(new Runnable() {
#Override
private void run() {
while(true) {
//your code goes here
}
}
});
Although AsyncTask allows you to perform background operations and publish results on the UI thread without having to manipulate threads, it should ideally be used for short operations (a few seconds at the most).
To keep things simple, you could use a Handler, or even better, research about the various APIs provided by the java.util.concurrent package.
import android.os.Handler;
// Create the Handler
private Handler handler = new Handler();
// Define the code block to be executed
private Runnable runnable = new Runnable() {
#Override
public void run() {
// Insert simulation processing code here
// Repeat 60 times per second
handler.postDelayed(this, 1000 / 60);
}
};
// Start the Runnable immediately
handler.post(runnable);
Remember that multi-threading is the easy part. Correct synchronization is hard.
I am using priority job queue , there are number of jobs running in parallel, so that their result populates on UI at same time which takes application to ANR, is there any way , so that i can run asynchronous calls and populate ui synchronously?
UI is always populated synchronously, if it is done in correct way. The correct way is to call activity.runOnUiThread(Runnable), directly or indirectly. Seems that your problem is that your jobs post to UI thread in a too high rate.
First, check if the Runnables to update UI does only UI work. Any calculations should be done outside the UI thread. If it is so, create an intermediate object which makes pauses between UI updates from the parallel jobs and so lets the UI thread to respond to updates from user. It can look as follows:
public class PauseMaker {
Semaphore sem = new Semaphore(1);
public void runOnUiThread(Runnable r) {
sem.aquire();
Thread.sleep(1);
activity.runOnUiThread(new Runnable(){
try {
r();
} finally {
sem.release();
}
});
}
}
You can use the zip operator of rxjava2 to merge the responses together and when the combined response comes you can populate the UI synchronously .. for reference you can check..
http://www.codexpedia.com/android/rxjava-2-zip-operator-example-in-android/
Note The zipper will the return merged response after all the responses are received
I am using a threadpool with only one thread to execute some network tasks (They need to be executed sequentially)through a viewholder in a RecyclerView in Android. It is working, if I am scrolling slow. But if I am scrolling fast, too many tasks will be pushed to the queue, which I have discovered through debugging, is blocking the queue entirely.
I have simplified the code (much) where I am using the one threaded threadpool:
if (executorService == null) {
executorService = Executors.newFixedThreadPool(1);
}
executorService.execute(new Runnable() {
#Override
public void run() {
RessourceService.getCoverPage(url, callback);
while (waiting) {}
}
});
So what is the alternatives, if I want to execute network tasks sequentially without getting a blocked queue?
Have you tried using newSingleThreadExecutor()
public static ExecutorService newSingleThreadExecutor()
Creates an Executor that uses a single worker thread operating off an
unbounded queue.
(Note however that if this single thread terminates
due to a failure during execution prior to shutdown, a new one will
take its place if needed to execute subsequent tasks.)
Tasks are guaranteed to execute sequentially, and no more than one task will be
active at any given time. Unlike the otherwise equivalent
newFixedThreadPool(1) the returned executor is guaranteed not to be
reconfigurable to use additional threads.
(Posted answer on behalf of the question author).
The problem was somewhere else in my code and not in that posted in the question. As described in my question, I am executing the requests through a viewholder of a recyclerview. When scrolling fast, the images are not loaded. I found out that the problem was occurring when an item was out of sight in the recyclerview. The reason for this, was that the request was locked due to my "waiting" variable being true. I could solve it by making it static and setting it to false right before each request and thereby stopping the request in progress in another viewholder.
Nevertheless, the suggesting by #Jessie Brian Revil on using newSingleThreadExecutor, makes perfectly sense. Not a direct solution to my problem, but a reasonable solution for the code above (therefore accept).
I have this piece of code running on Thread, for Android device. It was initially sufficient, but now I have a change in requirements that requires me to return the result after a HTTP POST. The "POST" function is in another class, so the code below will not work.
I read that RunnableFuture allows extraction of results for return of result. Can someone guide me on how to change this piece of code to that?
public ArrayList<String> addfood(final String status, final String spaceId) {
Log.d(TAG, "Add Food");
final ArrayList<String> results = new ArrayList<>();
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
String cookie = android.webkit.CookieManager.getInstance().getCookie(sURL);
Uri.Builder builder = new Uri.Builder()
.appendQueryParameter(“status”,status)
.appendQueryParameter("cookie", cookie)
.appendQueryParameter("space", spaceId);
String addresult = foodpost(POST(url, builder));
results.add(addresult);
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
return results;
}
let me clarify you a pair of things:
Analyzing your piece of code you're trying to access to another method of other class (as you said in your comment) from inside of one thread:
The "POST" function is in another class, so the code below will not work
It doesn't work because you have to have a reference to the other object in order to use the method.
But let me ask you a couple of things:
Concurrency is hard (very hard). Even if after modifying your piece of code to use properly the POST method, have you ever considered what happens with that thread? What happens when the user decides to rotate the device? What happens when your UiThread (the thread responsible of updating all UI elements of your application) decides to read that list of resutls (is thread safe also?)? I mean there are a lot of considerations to take care before creating a thread to do some background operation. And trust me, is very easy to do things wrong. Maybe it can leak memory and your app may become an unresponsive one. Do you think is neccesary?
There are a lot of libraries that can help you to achieve that network request in a easy manner, carrying the weight of doing background things for you. Those libraries are very battle tested, it has a decent amount of user base. Libraries like Retrofit or Volley are very good options to do whatever thing you want to achieve. So is there a need for not using that?
Sorry if I discourage you to use the thread, but there are a lot of useful options that would help you in the long run.
When I run replication on Couchbase Lite in Android from UI Thread, it happens that the replication executes in another thread and notifications (Via addChangeListener() method) are received in a third Thread. My code for Pull Replication is as follow:
Replication pullRep = getDatabase().createPullReplication(syncUrl);
pullRep.setContinuous(true);
pullRep.addChangeListener(this);
pullRep.start();
My question is: How can I run synchronous replication or at least get notifications on the same Thread from which replication was started ?
My opinion is that replication must occur in the current thread. The developer must handle thread issues.
I´m very new with Couchbase Lite and maybe I´m wrong.
I apologize if I'm misunderstanding your situation, but I believe what you're trying to say is you can't update the UI with changes discovered in the Couchbase listener because the listener operates on a background thread and not the UI thread. Am I correct?
You definitely don't want to run potentially long tasks on the UI thread because it will create a poor UX. Asynchronous is the way to go.
You might try something like this instead:
Handler threadHandler = new Handler();
couchbaseDatabase.addChangeListener(new Database.ChangeListener() {
public void changed(Database.ChangeEvent event) {
// Alter variables related to the UI (maybe an array for a list view)
threadHandler.post(updateUI);
}
});
final Runnable updateUI = new Runnable() {
public void run() {
// Refresh the UI
adapter.notifyDataSetChanged();
}
};
Of course what I pasted is just bits and pieces and not a true working example. My point here is that I used a Handler. There are a ton of other ways that will work as well.
Would this work for you?
Best,