What does an "asynchronous method" mean in Java? - java

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
}

Related

SIGSEV when calling JAVA callback method from native code after multiple calls

I am using JNA to pass a callback function from Java to native code. I am able to call the java inteface method ok, the problem is after about 40 calls of the function i get a SIGSEV and the program terminates.
The SIGSEV occurs at the line when the native code calls the method.
Is this related so some garbage collection on the Java function handle? Is there a way to prevent this?
Note: The closest thread on the sight was "SIGSEV when calling Java method from native pthread". He seemed solve his problem on the native side though by making things global.
I have tried making the java method synchronous but this has not helped. I also modified the native call to launch a pthread and then call the java method. When doing this, the method can be called maybe 1000 times then i get the SIGSEV
on the java side I have
public interface handler extends Callback {
void invoke();
}
static class test_start implements handler {
public synchronized void invoke() {
System.out.println("Hello");
}
}
You are right, that you suspect GC to be your problem, which is also documented in JNA.
Summary: You'll need to keep a strong reference to your Callback Handler on the java side to prevent garbage collection.
The implementation is highly dependent on your architecture. If your handler is global, you can save it in a static field (GC will normally collect static field data only when class is unloaded). If your handler is tied to a concrete java class, you could use a static WeakHashMap to keep the reference until the java object is collected (assuming this also indicates, that the native side will not call the handler anymore). If the handler is tied to a fixed lifecycle, I would implement an AutoCloseable helper object, that unregisters your handler on close.
It should be noted, that in all implementations, you must make sure that your handler is kept referenced. For the AutoClosable implementation running Reference#reachabilityFence​ from the close method after the handler is unregister would be a sane decision.

Attempt execution uniquness in a java project?

I am working a java library, which has a singleton class with a methods - createTask() and addPointsToTask()
The library is meant to be used in any java service which executes multiple requests.
The service should be able to call createTask only once during it's processing of a single request. Any further calls to createTask in the same thread execution should fail. addPointsToTask can be called any number of times.
As a library owner how can I restrict this method to be called only once per thread?
I have explored ThreadLocal, but don't think it fits my purpose.
One solution is to ask the service that is using the library to set a unique id in threadLocal, but as this 'set-to-thread-local' solution is outside the boundary of the library, this is not a full-proof solution.
Any hints?
Short answer: you won't get a "fool-proof" solution; i.e. a solution that someone can't subvert.
Unless you are running your library on a JVM platfrom that you control, users of your library will be able to find a way to subvert your "only once per thread" restriction if they try hard enough. For example:
They could use reflection to access the private state of the objects or classes that implement the restriction.
They could use bytecode injection to subvert your code.
They could decompile and replacing your code.
They could modify their JVM to do something funky with your code. (The OpenJDK source code is available to anyone.)
Ask yourself the following:
Is this restriction reasonable from the perspective of the programmer you are trying to restrict?
Would a sensible programmer have good reason to try to break it?
Have you considered possible use-cases for your library where it would be reasonable to call createTask() multiple times? For example, use-cases that involve using thread pools?
If you are doing this because you think allowing multiple createTask() calls will break your library, my advice would be:
Tell the programmer via the javadocs and other documentation what is likely to break if they do the thing that you are trying to prevent.
Implement a "soft" check, and provide an easy way for a programmer to disable the check. (But do the check by default, if you think that is appropriate.)
The point is that a sensible programmer won't knowingly subvert restrictions unless they have good reason to. If they do, and they hurt themselves, that is not your problem.
On the other hand, you are implementing this restriction for "business reasons" or to stop "cheating" or something like that, my advice would be to recognize that a determined user will be able to subvert any restrictions you attempt to embed in your code when they run it on their platform. If this fundamentally breaks your model, look for a different model.
You will not be able to prohibit multiple calls from the same request, simply because your library has no concept of what a "request" actually is. This very much depends on the service using the library. Some services may use a single thread per request, but others may not. Using thread-locals is error-prone especially when you are working in multi-threaded or reactive applications where code processing a request can execute on multiple parallel threads.
If your requirement is that addPointsToTask is only called for a task that was actually started by some code that is processing the current request, you could set up your API like that. E.g. createTask could return a context object that is required to call addPointsToTask later.
public TaskContext createTask() {
}
public void addPointsToTask(TaskContext context, ....) {
}
This way you can track task context even over multiple different threads executing code for the same request and points will not get added to a task created by another request.
You could add a method to your singleton which runs some piece of Service-Code in the context of a request.
Dummy implementation:
package stackoverflow;
import java.util.concurrent.Callable;
public enum YourLibrarySingleton {
INSTANCE;
private final ThreadLocal<Task> threadLocalTask;
YourLibrarySingleton() {
this.threadLocalTask = new ThreadLocal<>();
}
public void createTask() {
this.threadLocalTask.set(new Task() {});
}
public void addPointsToTask() {
Task task = this.threadLocalTask.get();
// add points to that task
}
public <T> T handleRequest(Callable<T> callable) throws Exception {
try {
return callable.call();
} finally {
this.threadLocalTask.remove();
}
}
}
Which could be used like this:
package stackoverflow;
public class ServiceCode {
public void handleRequest() throws Exception {
YourLibrarySingleton.INSTANCE.handleRequest(() -> {
YourLibrarySingleton.INSTANCE.createTask();
YourLibrarySingleton.INSTANCE.addPointsToTask();
YourLibrarySingleton.INSTANCE.addPointsToTask();
return "result";
});
}
}

Call a method once network call has been completed

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

Understanding callback methods

I am still confused about callback methods (new to OOP). One definition I found was: "A callback method in java is a method that gets called when an event occurs". What exactly decides when the method will be called? For example, in android, the activity class has an onCreate() callback method that executes whenever an Activity is created, but what code controls this?
Is the doInBackground method of the AsyncTask class also a callback method that executes whenever a foo.execute() is called, where foo is an AsyncTask object?
I see it quite simple like this: lets say you give me your phone number and I'll call you at sunrise. You don't have to worry about how I get up and call your "call-back number", as long as you trust me.
Its the same with a callback method. If the API documents you can supply a method and it will be called when a certain event happens, you don't have to worry about how that's done. Thats the responsibility of the creator of the API.

How to wait for an asynchronous task to return

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.

Categories

Resources