Im trying to call a method once a network call has been completed. I have tried using LocalBroadcastManager for this. I initially had it send the broadcast once the network call is complete, which worked fine, until i had
multiple methods waiting for the same intent, started causing problems.
Is there a better solution or is this the best way? If it is, could you point me to somewhere where i can learn how to use this in-depth or explain how its used?
Sorry i forgot to mention I am using Volley Library to do my network calls?
Thanks
you are using BroadcastManager than definitely because of android slow cycle it call receive method multiple time at some point. you can found same problem here.
you need to do is just to prevent calling method multiple time so use above link for hint of your problem, and hint is to take flag and Handler for prevent multiple call.
You should use callbacks to wait for the network task to be done.
The basis idea is the same like an onClickListener. You pass an interface implementation which will do the task what you want once the callback is called.
It should be something like this:
public interface OnComplete {
void onComplete();
void onError(String errorMsg);
}
When you call your network stuff you should pass an implementation like this:
NetworkManager.callServer("serverurl", new OnComplete() {
#Overwrite
void onComplete() {
//Do your stuff here
}
#Overwrite
void onError(String errorMsg){
}
}
And you call it from the NetworkManager:
//from the AsyncTask when you done with the network stuff
onComplete.onComplete();
If you have to wait for multiple calls you can use the CyclicBarrier: http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CyclicBarrier.html
Related
I got an AsyncTask for URL connection. Now I want to have a loading spinner everytime I do the URL connection. I display the loading spinner in onPreExecute() and dismiss it in onPostExecute.
I tested this with an endless while loop in doInBackgroung().
The big problem is the GUI is freezing and the loading spinner is not shown.
In my opinion the reason is URLconnection.execute().get(). But I need the get() because the activity need the result to working with it.
My question is now: What is the best way to do this to achieve my wishes? (By the way it is not important to get a solution with an "AsyncTask solution" because there are maybe better solutions and AsyncTask will be deprecated with SDK version 30)
Thank you very much and stay healthy!
As you said AsyncTask will be deprecated.
So it is better to go for an alternative.
Since you mentioned you are not relying on AsyncTask, I will present to you another approach.
Let me introduce you to coroutines and convince you that they will solve your problem and "get the job done".
When I got to know about coroutines, this video was one of the first example that has demonstrated to me the potential of using coroutines in my app. At that point I was still using 100% Java, probably like you are right now.
The good part is: getting started with Kotlin is really easy! Not only you can call Kotlin functions from Java Code, you can also call Java functions from Kotlin code.
To "do something in background" in Kotlin, all you need to do is to launch a coroutine (on a background thread).
Do you have a ViewModel to fetch your data? If it is an option to transfer this file to kotlin, then starting (and scoping) a coroutine becomes as simple as this.
For fragments or activitities you could use other copes as well. However, using the global scope is usually discouraged.
Executing coroutines is as simple as that:
class MyViewModel: ViewModel() {
fun loadDataInBackgroundAndShowSpinner {
viewModelScope.launch {
// Coroutine that will be canceled when the ViewModel is cleared.
// start your spinning
// do all the heave data work on a background thread
doInBackground()
// end your spinning here
}
}
suspend fun doInBackground(inputURL: String) {
withContext(Dispatchers.IO) {
// Execute all your data fetching here
...
// Assign your data to your viewModel variables, post it to a LiveData object, etc.
}
}
}
You do not need any loops in the main thread or anything. By using withContext on a background thread you can achieve main-safety.
Within a launched coroutine, everything (by default) gets executed in order.
Still you will not block the Main Thread. How did you achieve that?
The key here is that your doInBackground function has the suspend keyword. Therefore your loadDataInBackgroundAndShowSpinner on the main thread will "suspend" your doInBackground function and the main thread is able to do whatever you want (i.e. nothing freezes). Then, once your doInBackground is finished, it will resume execution and you can just dismiss your spinner again on the main thread.
Kotlin coroutines make it so much easier to do something in the background and I really want to encourage you to give it a try! It will definitely solve your problem and I can not think of a more easy way.
Google also tried to make it as easy as possible to get you started when coming from Java.
I am making a chat application.The server will send me an update whenever a friend sends me a message.As a result i need a continuous listener from my android client.I have used asynchronous task and in the post execute method, i have called the asynchronous task again.Thus listening continuously.But this is giving me weird errors.
If you could help me i would be really grateful.If you think i should implement the continuous listener in some other way please do suggest me.Thanks.
Proper method should be like when you get connected to server, you should keep listening in a loop. See my answer here
and modify it as needed.
What about using http://quickblox.com/developers/Android library? I am just curious, if it would not be easier :) .
Otherwise I thought about making while cycle in doInBackground() method, instead of calling asyncTask all over again.
Something like -
While(programExit) {
//your code
}
I am in the process of working through the android billing example for an app. The sample app refers to an asynchronous method. I have had a look on the web and I cant seem to find a good definition, please can someone help with an example.
Sample as follows:
// Start setup. This is asynchronous and the specified listener
// will be called once setup completes.
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
Is it a method that does not immediately return a result?
If I am not mistaken, you are referring to this method startSetup that accepts a final OnIabSetupFinishedListener and supposedly sets up the billing.
What you seem to be confused about, is this rather syntactically obscure feature of Java called the anonymous inner class.
Let me attempt to answer your question to make it easier:
Is it a method that does not immediately return a result?
Yes, sort of (it of course does not return anything for it is a void method). It, simply speaking, is a method that accepts an instance of the interface OnIabSetupFinishedListener and does some of its job asynchronously as stated in the Javadoc and returns nothing:
This will start up the setup process asynchronously.
Thus, this method is similar to what any other void Java method looks like. The only additional implementation information is that some kind of communication is set up between the listener you pass to this method and some other objects.
But that communication is going to happen at a later point in time, not at the time you call this method, startSetup. Thus, what is important is the call site, i.e. how you are going to call this method in your own app. This, hopefully, happens at the time of setting up your app and you need to get it quickly running and hence this method provides a callback mechanism and returns as soon as possible in a synchronous manner without unnecessary delay. This means your calling thread can make progress and the listener you passed to this method can be utilized later in some other thread when an appropriate event occurs.
The confusion also comes in part because of the way anonymous inner classes are typically coded. Thus, your call site may look like the following:
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
// Oh noes, there was a problem.
Log.d(TAG, "Problem setting up In-app Billing: " + result);
}
// Hooray, IAB is fully set up!
}
});
Here, you are providing an anonymous implementation of the interface OnIabSetupFinishedListener directly at the call site (without actually creating a separate class implementing that interface, using the construct like class MyListener implements OnIabSetupFinishedListener).
Yes. In this context, "asynchronous" means that the method will return immediately and execution will continue with the statement following the method call. Sometime later, the onIabSetupFinished(...) method will be called on the listener. This is called a callback. An important consideration with asynchronous callbacks is what thread they are called in. You'll need to refer to the documentation for this API to find that out.
An asynchronous method is not a typically request/response
You can think of this like a promise or something that will reply without pooling.
In your case you are creating an anonymous listener that will resolve the promise here
public void onIabSetupFinished(IabResult result){
//you will eventually get the response here
}
So I have a problem and I am wondering how to solve it if it can be solved at all.
I have an external library class called Messenger that defines the method sendMessage(String msg). I also have the following MessengerManager class
public class MessengerManager{
private Messenger messenger;
public MessengerManager(Context context){
messenger = new Messenger(context);
}
public void message(){
String msg = "12435";
messenger.sendMessage(msg);
// Do more stuff
.....
.....
.....
}
}
So the issue is that sendMessage runs asynchronously and starts a new activity. Probably using startActivity() (lets call this Activity A). Hence, the code after sendMessage ("Do more stuff") gets run immediately. However, I need to wait for the newly created activity (Activity A) to return to carry on with the "Do more stuff".
As sendMessage is a method defined in an external library, I cannot change it in any way nor do I have access to its source code.
So, in short, my problem is that sendMessage creates a new thread (using startActivity() probably) and I need to know when this newly created activity ends. However, I have no way of monitoring it since it is defined in an external library. Anyone know how to solve this?
AsyncTask should be what you are looking for.
Let your message() starts an AsyncTask that calls messenger.sendMessage(msg) in doInBackground(). If you care about the result of the AsyncTask, get it in onPostExecute().
http://developer.android.com/reference/android/os/AsyncTask.html
One admittedly ugly way to get around this is to call
Thread.sleep(int milliseconds)
after sendMessage(), and before you continue with the rest of your code. Of course, this will only be helpful if you can fairly accurately estimate how long it will take to get the callback.
The better alternative is as Kaifei is saying. But you won't want the "do more stuff" where it is now. Instead, put it in a new method, and call that method in onPostExecute(). That way, the code will not continue until the AsyncTask has returned.
Edit: Saw your addition about needing the created activity to finish. If that's the case, you're going to somehow need to communicate with that activity (which I can't speak to without seeing all the code). But if you have that, then before "do more stuff", insert
while(!activity.isFinished()) {}
and in that activity, have it set a finished variable to true when it is done (however you define done). So the main thread will run this loop until the activity on the second thread is done, and then the first thread will continue.
Double Edit: Another idea. Let's say that the other activity the user has to complete is some form. In your main activity, after you call sendMessage(), have some popup where the user selects "finished" when they have completed the new activity. Have the program only continue when "finished" has been selected. A bit annoying for the user, but if it's only a single additional tap, that should work.
As you mentioned, sendMessage() runs asynchronously. If it's written properly, it must also have provided a callback interface, whose method will be called when messaging is finished. Move the code in that callback method.
I am writing my first Android app(allot of fun so far!) and have run into a roadblock. I am using SDK tools 21.1 targeting Android 4.2.
I am trying to set up a system that allows activities to register to invoke a method at set time intervals. I wanted to do this in such a way that the processing of the request would be handled on it's own process to avoid making the UI unresponsive.
I have been doing some reading and have explored a few avenues. First I thought that a service would be a good way to go about this but found a fair bit of information suggesting that was not a good course of action due to the OS being able to kill services indiscriminately.
I'm now looking at using a ScheduledThreadPoolExecutor. I've created this simple class with an overridable method to pass methods around:
public abstract class BaseEvent implements EventListener {
public abstract void onFire(Object... params);
}
I've created this runnable task invoke the method:
public class HeartBeatTask implements Runnable {
private BaseEvent mCallback;
private Object mParams;
public HeartBeatTask(BaseAioEvent callback,Object... params){
mParams = params;
mCallback = callback;
}
#Override
public void run() {
Log.d(LOG_TAG,"Run called");
if(mCallback != null)
{
mCallback.onEvent(mParams);
}
}
}
I'm going to use it like this (inside an Activity)
ScheduledThreadPoolExecutor threadPool = new ScheduledThreadPoolExecutor(1);
BaseEvent callback = new BaseEvent() {
public void onFire(Object... params){
if(params[0] !=null)
{
Context context = (Context)params[0];
Toast toast = Toast.makeText(context, "Task ran", Toast.LENGTH_SHORT);
toast.show();
}
}
};
threadPool.scheduleAtFixedRate(new HeartBeatTask(callback,(this)),0, 5, TimeUnit.SECONDS);
This will execute the task every 5 seconds, although the callback method is only being run once.
I'm thinking that this may not be a good way to do things. My feeling is that I'm overcomplicating things. What I really need is the ability to have something that will execute a method, on a process other than the main thread, and at a set interval, that activities can bind multiple actions to. So, for instance, I may want to have a UI component update after a call is made to a database, and would want that to happen every minute.
Could any tell me if I am on the right track here? Is what I am trying to do a viable way to accomplish my goal? Is there a better approach I could be taking? Any advice or suggestions would be very much appreciated. Thanks!
a few suggestions for an Android beginner.
Don't call it a separate process. Process is a different thing (Google 'Linux process'), you want to call them on a separate thread inside the same process.
ScheduledThreadPoolExecutor IS better than anything else people will suggest you here such as Timers or PostDelayed.
But I think you do have a philosophical error here as to UI updates shouldn't be running on a timed manner but on an event base instead. Once your Db, Disk or Network operation finishes from a background thread you callback to the UI thread to update it immediately.
There`re several tools for that and I'll list a few, point the one I like the best, but let you do some research on each one
Handler: That's basic java way
AsyncTask: Nice framework but doesn't handle screen rotation
Loader: That's my preferred way
I think your approach is a bit complicated. Consider you example
So, for instance, I may want to have a UI component update after a call is made
to a database, and would want that to happen every minute.
I think I will do it this way.
Create a AsyncTask which will update the UI component.
Create a thread which will execute a new AsyncTask and sleep one minute in a while loop.
Start the thread in step 3. at some point.
Interrupt the thread if you don't want the component to be updated.
Example of step 2
while (true) {
try {
new updateTask.execute();
Thread.sleep(60000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
Android is a mobile platform and in all honesty each time you want something run, you better consider it separately. You may be killing the battery or using resources for no reason. I begrudge Zedge app everyday for running for no reason in the background at all times. Especially since on CyanogenMod kernel puts WiFi to sleep, while apparently it is currently on.
I am guessing this is more of an exercise and for running tasks at a specified intervals. One-offs, most universal can be done via AlarmManager class. But this may not be the best solution.
For some system wide events there is the BroadcastReceiver class.
While addressing
So, for instance, I may want to have a UI component update after a call is made to a database, and would want that to happen every minute.
Easier done via an Interface really.