I have a native android app using volley framework to fetch data from a PHP server end script.
It worked well on most time, but I have 20% percentage failure.
The error says:
com.android.volley.NoConnection, java.io.InterruptedIOException.
I debugged that I found the statuscode = 0, which obviously was wrong.
I have no idea what can be the reason? Since it is working most time so there should be no obvious error code.
FYI, those PHP script on the server end works very well for my IOS app.
Please allow me post my code here:
retryConnBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
txtOut.append("\n");
txtOut.append("Button with Retry Click");
Log.d("Click", "Button Click");
final String url = "https://www.myserver.com/api/getBalanceInfoTest?token=7ff3317a4f3dc07d0c297a7d16d2049c&t=" + System.currentTimeMillis();
//final String url = "http://192.168.1.23/base/test/";
JsonObjectRequest getRequest = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
txtOut.append("\n");
txtOut.append("Result with Retry:");
txtOut.append(response.toString());
Log.d("Response", response.toString());
VolleyLog.e("Response:", response.toString());
}
},
new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error) {
txtOut.append("\n");
txtOut.append("Error with Retry:");
txtOut.append(error.toString());
Log.d("Error.Response", error.toString());
VolleyLog.e("Error:", error.getMessage());
}
});
getRequest.setRetryPolicy(new DefaultRetryPolicy(5000, 5, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(getRequest);
queue.start();
}
});
}
And for more information, the output of my PHP script is:
{"hsaBalance":"1000.00"}, created by Json_encode() function of PHP.
I have fixed this bug.
It is not a network issue.
queue.add(getRequest);
queue.start();
should be
queue.add(getRequest);
So the key is we should remove queue.start().
Michael Cheng is right,because volley had start the RequestQueue when we call newRequestQueue as below:
public static RequestQueue newRequestQueue(Context context, HttpStack stack) {
File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);
String userAgent = "volley/0";
try {
String packageName = context.getPackageName();
PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
userAgent = packageName + "/" + info.versionCode;
} catch (NameNotFoundException e) {
}
if (stack == null) {
if (Build.VERSION.SDK_INT >= 9) {
stack = new HurlStack();
} else {
// Prior to Gingerbread, HttpUrlConnection was unreliable.
// See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
}
}
Network network = new BasicNetwork(stack);
RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);
queue.start();
return queue;
}
and when we call start, volley will call stop to “make sure any currently running dispatchers are stopped”,in stop method volley does this below:
public void stop() {
if (mCacheDispatcher != null) {
mCacheDispatcher.quit();
}
for (int i = 0; i < mDispatchers.length; i++) {
if (mDispatchers[i] != null) {
mDispatchers[i].quit();
}
}
}
and the quit method does this below:
public void quit() {
mQuit = true;
interrupt();
}
maybe you can see the reason,why interrupted.
More, interrupt method does this below:
public void interrupt() {
// Interrupt this thread before running actions so that other
// threads that observe the interrupt as a result of an action
// will see that this thread is in the interrupted state.
nativeInterrupt();
synchronized (interruptActions) {
for (int i = interruptActions.size() - 1; i >= 0; i--) {
interruptActions.get(i).run();
}
}
}
the reason maybe this as metioned above:
Interrupt this thread before running actions so that other threads that observe the interrupt as a result of an action will see that this thread is in the interrupted state.
You are having sometimes problems with your connection. Look at InterruptedIOException API:
InterruptedIOException Signals that an I/O operation has been interrupted. An InterruptedIOException is thrown to indicate that an input or output transfer has been terminated because the thread performing it was interrupted.
so only you can do is to catch the possible exceptions occuring when converting JSon and having a workaround for this.
// rest of your code...
final String url = "https://www.myserver.com/api/getBalanceInfoTest?token=7ff3317a4f3dc07d0c297a7d16d2049c&t=" + System.currentTimeMillis();
try {
JsonObjectRequest getRequest = new JsonObjectRequest(Request.Method.GET, url, null,
// rest of your code...
queue.add(getRequest);
queue.start();
} catch (InterruptedIOException e) {
// do something when fail print error, show a toast
System.out.err("Error, connection interrupted" + e.getMessage());
Toast.makeText(getApplicationContext(), "press button again", Toast.LENGTH_LONG).show();
}
Related
I'm trying to do something similar to the answer of this question
I'm using Volley rather than Retrofit, and have adapted my code accordingly. For me the callback handlers never actually fire, although the counDownLatch does timeout after the specified number of seconds. I suspect the handlers never fire because the countDownLatch.awaiting is using all the processing on the current thread. Or am I missing something else?
public void queryUmbrellaServer() {
ArrayList<String> identifiers = getHardwareIdentifiers(context);
VolleyLog.DEBUG = true;
CountDownLatch countDownLatch = new CountDownLatch(identifiers.size());
// creating a new variable for our request queue
final RequestQueue[] queue = {Volley.newRequestQueue(context)};
queue[0].start();
for (int i = 0; i < identifiers.size(); i++) {
String url = umbrellaServerUrl + identifiers.get(i) + "/";
Log.i(LOG_TAG, "Inside Loop " + url);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
countDownLatch.countDown();
String serverName = response.getString("mdm_server_url");
String registrationUrl = response.getString("registration_url");
String isDeviceOwner = response.getString("device_owner");
Toast.makeText(context, "Retrieved server name from umbrella server: " + serverName, Toast.LENGTH_LONG).show();
setMdmInfo(serverName, registrationUrl, isDeviceOwner);
Log.i(LOG_TAG, "Successful response");
//queue[0].stop();
results.add(isDeviceOwner.toString());
} catch (JSONException e) {
e.printStackTrace();
Log.d(LOG_TAG, "Error in parsing response");
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
countDownLatch.countDown();
if(error.networkResponse.data!=null) {
String jsonString = new String(error.networkResponse.data);
//Log.d(LOG_TAG, jsonString);
try {
JSONObject jsonObject = new JSONObject(jsonString);
String msg = jsonObject.getString("message");
if (!msg.equals("Device not found")) {
Log.d(LOG_TAG, "Error in retrieving response from server");
//queue[0].stop();
results.add("false");
}
else {
Log.d(LOG_TAG, "No device found");
results.add("false");
}
} catch (JSONException e) {
e.printStackTrace();
Log.d(LOG_TAG, "Error in retrieving response from server");
//queue[0].stop();
results.add("UNSET");
}
}
else {
Log.d(LOG_TAG, "Error in retrieving response from server");
//queue[0].stop();
results.add("UNSET");
}
}
});
// Add the request to the RequestQueue.
queue[0].add(jsonObjectRequest);
}
try {
countDownLatch.await(1L * identifiers.size(), TimeUnit.SECONDS); // join thread with timeout of second for each item
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(LOG_TAG,"outside loop" + results);
}
I expected the results arrayList should get populated before the countDownLatch countdown completes, but I haven't been able to get any results.
I'm trying to pull the text and blocks from my image processed through a FirebaseVisionTextRecognizer, and even though the processing is successful, it doesn't seem to return as the correct type. Android studio reports that result is of type Task<FirebaseVisionText> instead of type FirebaseVisionText, as the documentation suggests it should.
Here is the problem area:
'''FirebaseVisionImage fImg = FirebaseVisionImage.fromBitmap(curBitmap);
FirebaseVisionTextRecognizer tscan = FirebaseVision.getInstance().getOnDeviceTextRecognizer();
System.out.println("before task");
Task<FirebaseVisionText> result =
tscan.processImage(fImg)
.addOnSuccessListener(new OnSuccessListener<FirebaseVisionText>() {
#Override
public void onSuccess(FirebaseVisionText firebaseVisionText) {
System.out.println("task success");
// Task completed successfully
// ...
}
})
.addOnFailureListener(
new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
System.out.println("task fail");
// Task failed with an exception
// ...
}
});
String str = result.getText();'''
The line:
String str = result.getText();
reports the error: Cannot resolve method 'getText' in 'Task'
I tried casting result to FirebaseVisionText as well as setting a new FirebaseVisionText equal to result, but neither solved the problem.
I fixed the issue by replacing String str = result.getText(); with Tasks.await(result); return result.getResult(); and calling the containing function on a new thread: new Thread(new Runnable() { public void run() { try{ containingFunction();} catch {}}}).start();
I have an onClickListener that uses Okhttp to asynchronously get some stuff in the background. Here's the OnClickListener:
mGetChartButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String companyName = mSymbolValue.getText().toString();
getRequest(companyName, "chart");
Log.i(TAG, mChartProfile.getSizeDates()+""); // Null exception happens here
}
});
And here is the Okhttp snippet:
OkHttpClient client = new OkHttpClient();
Request request = new Request
.Builder()
.url(completeUrl)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
#Override
public void onResponse(Call call, Response response) throws IOException {
try {
String jsonData = response.body().string();
Log.v(TAG, jsonData);
if (response.isSuccessful()) {
if (requestType.equals("quote")) {
isValidSearch = getQuote(jsonData);
runOnUiThread(new Runnable() {
#Override
public void run() {
if (isValidSearch) {
updateDisplay();
}
toggleFacts(isValidSearch);
}
});
}
else{
getChartInfo(jsonData);
}
} else {
alertUserAboutError();
}
} catch (IOException e) {
Log.e(TAG, "Exception caught: ", e);
} catch (JSONException e) {
Log.e(TAG, "JSONException caught: ", e);
Toast.makeText(BuyActivity.this, "oops!", Toast.LENGTH_LONG).show();
}catch (ParseException e){
Log.e(TAG, "Unable to parse", e);
}
}
});
// How do I do a thread.join() here?
private void getChartInfo(String jsonData) throws JSONException, ParseException{
JSONObject wholeChartData = new JSONObject(jsonData);
JSONArray dates = wholeChartData.getJSONArray("Dates");
mChartProfile = new ChartProfile();
// ChartProfile contains ArrayList of ChartDate and ArrayList of ChartValue
for (int i = 0; i < dates.length(); i++){
ChartDate chartDate = new ChartDate(dates.getString(i));
mChartProfile.addToDates(chartDate);
}
JSONArray values = close.getJSONArray("values");
for (int i = 0; i < values.length(); i++){
ChartValue chartValue = new ChartValue(values.getDouble(i));
mChartProfile.addToValues(chartValue);
}
}
Right now, I'm getting an error of thread exiting with uncaught exception. And this is caused by a null exception because when calling mChartProfile.getSizeDates(), the values haven't been written in yet. My intuition is that the call to getChartInfo(jsonData) doesn't finish and the main UI thread is already returning from the getRequest() function. Hence, it will continue next line, and try to access an empty array that has not been initialized. Hence, I get a null exception. My solution is to have the main thread wait on the worker thread by calling thread.join() but I am not sure of how to do this through this Okhttp interface. Any help is deeply appreciated.
Today I found a wierd problem. What I want is to check server availability (Particularly SSL checking) once application started and display proper message if server is down. This process should work in background and user is able to navigate the app if server has problem (app can works offline).
What I did is simple. In main activity I have
#Override
protected void onStart()
{
super.onStart();
// Check Internet connection
// Check Location sensor
// Check server accessibility
BackendCheck backendCheck = new BackendCheck(this);
if (!backendCheck.execute())
{
displayErrorDialog();
return;
}
}
This is BackendCheck class:
public class BackendCheck implements Callable<Boolean>
{
private static final String TAG = BackendCheck.class.getSimpleName();
// Thread sleep time
private static final int THREAD_SLEEP = 5000;
// Number of attempts to call an API in order to get response
private static final int MAX_ATTEMPT = 3;
// Current attempt
private int counter = 0;
// The url that should be used in order to get server response
private String mTestUrl;
// App mContext
private Context mContext;
// Server status
private boolean mServerStatus = false;
public BackendCheck(Context context)
{
this(context, "");
}
public BackendCheck(Context context, String url)
{
this.mTestUrl = url;
this.mContext = context;
}
public boolean execute()
{
// Check #mTestUrl and use Feature API if this variable is empty
if (TextUtils.isEmpty(mTestUrl))
{
mTestUrl = PassengerConstants.URL_BASE + mContext.getResources()
.getString(R.string.uri_feature_payments);
}
// Get ExecutorService from Executors utility class, thread pool size is 10
ExecutorService executor = Executors.newFixedThreadPool(10);
do
{
// Increment counter
counter++;
// Submit Callable tasks to be executed by thread pool
Future<Boolean> future = executor.submit(this);
try
{
// Break Do-While loop if server responded to request (there is no error)
if (!future.get())
{
mServerStatus = true;
break;
}
}
catch (InterruptedException e)
{
Logger.error(TAG, e.getMessage());
}
catch (ExecutionException e)
{
Logger.error(TAG, e.getMessage());
}
} while (counter < MAX_ATTEMPT);
// Shut down the executor service now
executor.shutdown();
// Return server status
return mServerStatus;
}
#Override
public Boolean call() throws Exception
{
// Sleep thread for a few seconds
Thread.sleep(THREAD_SLEEP);
try
{
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(mTestUrl);
Logger.debug(TAG, "Attempt (" + counter + "), try to check => " + mTestUrl);
HttpResponse httpResponse = client.execute(get);
int connectionStatusCode = httpResponse.getStatusLine().getStatusCode();
Logger.debug(TAG,
"Connection code: " + connectionStatusCode + " for Attempt (" + counter
+ ") of request: " + mTestUrl);
if (isServerError(connectionStatusCode))
{
return true;
}
}
catch (IllegalArgumentException e)
{
Logger.error(TAG, e.getMessage());
}
catch (Exception e)
{
Logger.error(TAG, e.getMessage());
}
return false;
}
/**
* Server status checker.
*
* #param statusCode status code of HTTP request
* #return True if connection code is 5xx, False otherwise.
*/
private static boolean isServerError(int statusCode)
{
return (statusCode >= HttpURLConnection.HTTP_INTERNAL_ERROR);
}
}
What happens is, When I launch the application splash screen displays. Then after a few seconds mainActivity runs (first code) then - since my server is down (for testing purposes) - I have black screen for 15 seconds (since I set MAX_ATTEMPT to 3 and have 5 seconds thread sleep) and after that I'm able to see UI of mainActivity and my error message.
I expect Callable<> should works in background and I see mainActivity after splashScreen without problem (black screen).
What you think? What problem might be? Thanks.
It would appear that you are executing the BackendCheck callable in the main thread.
Classes that extend Callable are usually executed via an ExecutorService which is a separate thread itself, thus it executes in the background. You may want to take a look at the Runnable interface or Thread if you'd like to run a separate thread to execute in the background that does not return a value. Calling the start method will cause the class to execute in a separate thread as indicated by the documentation:
When an object implementing interface Runnable is used to create a thread, starting the thread causes the object's run method to be called in that separately executing thread.
If you need to return some data at the end of execution I highly recommend an ExecutorService but you could probably also get away with using a FutureTask though I have less experience with that class. Hopefully that helps.
Okay, I just fixed my problem. 'njzk2' is right. The problem is future.get() which is running on or blocking main thread. I fixed the issue by doing a few changes.
First, I call my execute() method from a new thread. Therefore the whole of processing will be done in another thread.
I added new start() method in order to run it.
Add a listener in BackendCheck class and implemented it in my activity.
Since I want to display a dialog if server is down and I'm in another thread then runOnUiThread(runnable) uses to show the dialog in main thread.
This is my complete code for your reference.
In my activity:
#Override
protected void onStart()
{
super.onStart();
// Check Location sensor
// Check server accessibility
BackendCheck backendCheck = new BackendCheck(this);
backendCheck.setServerListener(new BackendCheck.BackendCheckListener()
{
#Override
public void onServerIsDown()
{
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
displayErrorDialog();
}
});
}
});
backendCheck.start();
}
And my BackendCheck class:
public class BackendCheck implements Callable<Boolean>
{
public interface BackendCheckListener
{
public void onServerIsDown();
}
private static final String TAG = BackendCheck.class.getSimpleName();
// Thread sleep time
private static final int THREAD_SLEEP = 5000;
// Number of attempts to call an API in order to get response
private static final int MAX_ATTEMPT = 3;
// Current attempt
private int counter = 0;
// The url that should be used in order to get server response
private String mTestUrl;
// App mContext
private Context mContext;
// Server status
private boolean mIsServerWorking = false;
// Server listener
private BackendCheckListener mListener;
public BackendCheck(Context context)
{
this(context, "");
}
public BackendCheck(Context context, String url)
{
this.mTestUrl = url;
this.mContext = context;
}
public void setServerListener (BackendCheckListener listener)
{
this.mListener = listener;
}
public void start()
{
Thread thread = new Thread()
{
#Override
public void run() {
boolean isServerWorking = execute();
if(!isServerWorking)
{
mListener.onServerIsDown();
}
}
};
thread.start();
}
private boolean execute()
{
// Check #mTestUrl and use Feature API if this variable is empty
if (TextUtils.isEmpty(mTestUrl))
{
mTestUrl = PassengerConstants.URL_BASE + mContext.getResources()
.getString(R.string.uri_feature_payments);
}
// Get ExecutorService from Executors utility class
ExecutorService executor = Executors.newFixedThreadPool(1);
do
{
// Increment counter
counter++;
// Submit Callable tasks to be executed by thread pool
Future<Boolean> future = executor.submit(this);
try
{
// Skip sleeping in first attempt
if(counter > 1)
{
// Sleep thread for a few seconds
Thread.sleep(THREAD_SLEEP);
}
// Break Do-While loop if server responded to request (there is no error)
if (!future.get())
{
mIsServerWorking = true;
break;
}
}
catch (InterruptedException e)
{
Logger.error(TAG, e.getMessage());
}
catch (ExecutionException e)
{
Logger.error(TAG, e.getMessage());
}
} while (counter < MAX_ATTEMPT);
// Try to shut down the executor service now
try
{
executor.shutdown();
executor.awaitTermination(THREAD_SLEEP, TimeUnit.MILLISECONDS);
}
catch (InterruptedException e)
{
Logger.error(TAG, e.getMessage());
}
// Return server status
return mIsServerWorking;
}
#Override
public Boolean call() throws Exception
{
try
{
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(mTestUrl);
Logger.debug(TAG, "Attempt (" + counter + "), try to check => " + mTestUrl);
HttpResponse httpResponse = client.execute(get);
int connectionStatusCode = httpResponse.getStatusLine().getStatusCode();
Logger.debug(TAG,
"Connection code: " + connectionStatusCode + " for Attempt (" + counter
+ ") of request: " + mTestUrl);
if (isServerError(connectionStatusCode))
{
return true;
}
}
catch (IllegalArgumentException e)
{
Logger.error(TAG, e.getMessage());
}
catch (Exception e)
{
Logger.error(TAG, e.getMessage());
}
return false;
}
/**
* Server status checker.
*
* #param statusCode status code of HTTP request
* #return True if connection code is 5xx, False otherwise.
*/
private static boolean isServerError(int statusCode)
{
return (statusCode >= HttpURLConnection.HTTP_INTERNAL_ERROR);
}
}
I'm writing an Android messaging application, and 1 class is calling another class, and I wish for the calling class to wait for the callee class to complete before carrying on.
Caller Class (MessageManagement) code snippet is as follows:
private static Messenger myMessenger;
try {
Message msg = Message.obtain();
msg.arg1 = constructedMessage.length();
msg.arg2 = -1;
msg.obj = constructedMessage;
Log.d(TAG, "Calling myMessenger.send()");
myMessenger.send(msg);
Log.d(TAG, "Sent");
} catch (Exception e) {
e.printStackTrace();
}
// Wait here until myMessenger completes its task
doOtherStuff();
Right now, doOtherStuff() starts and finishes before myMessenger starts. I need myMessenger to complete before doOtherStuff() starts.
I've read about wait() and notify() but I'm not sure how to implement it here, or whether it's the right choice.
Some background about the flow of the program. It's basically a messaging app that I inherited, so I'm not exactly sure of its framework. From what I can tell tracing the flow of the code:
When an SMS message is received, the SMS receiver BroadcastReceiver(SmsReceiver) handles it, getting the sender address and message body, then calling a SMS handler service(HandleSmsService), which then calls the caller class in a runnable with the following code:
HandleSmsService
public class HandleSmsService extends Service {
private String message;
private MessageManagement messageManager;
private Handler timeoutHandler = new Handler();
#Override
public void onStart(Intent intent, intent startid) {
message = intent.getExtras().getString("message");
messageManager = new MessageManagement(this);
timeoutHandler.postDelayed(runnable, 10);
}
private Runnable runnable = new Runnable() {
#Override
public void run() {
try {
messageManager.handleMessage(message);
stopSelf();
} catch (Exception e) {
e.printStackTrace();
}
}
};
MessageManagement is my caller class, and MessageManagement.handleMessage() is the top most code snippet presented earlier.
The MessageManagement.handleMessage() apparently calls another Handler in the callee class when it calls myMessenger.send(msg). This Handler code is as follows:
private Handler smsHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
// do some stuff
}
};
I'm assuming the posted code is running on the MainThread and the reason why you are using a handler is that something asynchronous is done on another thread when receiving that message.
In that case, you can't use wait on the thread, as it will lock up the UI and probably cause an application not responding error.
Without changing too much of your code, one way to do it is to nest a listener in your constructedMessage for e.g.
public class DoStuffRequest {
private OnFinishListener mOnFinishListener;
private boolean isCanceled;
private String mMessage;
public interface OnFinishListener {
public void onFinish();
}
public DoStuffRequest(String message) {
mMessage = message;
}
public OnFinishListener getOnFinishListener() {
return mOnFinishListener;
}
public void setOnFinishListener(OnFinishListener onFinishListener) {
mOnFinishListener = onFinishListener;
}
public void cancel() {
isCanceled = true;
}
public void notifyFinish() {
if (!isCanceled && mOnFinishListener != null) {
mOnFinishListener.onFinish();
}
}
public String getMessage() {
return mMessage;
}
}
then use some along the line of this to get the ball rolling:
private static Messenger myMessenger;
private DoStuffRequest mRequest;
...
private void send(String message) {
mRequest = new DoStuffRequest(message);
mRequest.setOnFinishListener(new ConstructedMessage.OnFinishListener() {
#Override
public void onFinish() {
doOtherStuff();
}
});
try {
Message msg = Message.obtain();
msg.arg1 = constructedMessage.length();
msg.arg2 = -1;
msg.obj = constructedMessage;
Log.d(TAG, "Calling myMessenger.send()");
myMessenger.send(msg);
Log.d(TAG, "Sent");
} catch (Exception e) {
e.printStackTrace();
}
}
private void doThisIfYouWantToCancel() {
if (mRequest != null) {
mRequest.cancel();
}
}
your Handler/Service code can now call constructedMessage.finish() when the async stuff is done. Depending on what doOtherStuff() does (e.g. when manipulating the UI), you might want to do this on the MainThread (the code i've written above is NOT thread safe and i assume you are calling the listener on the MainThread).
Also remember to call constructedMessage.cancel() in case you do not want to get notified any more (e.g. you are leaving the activity/fragment).
this is just one way to do it, depending on your needs, some other methods might be a better choice.
I guess it should look something like this:
try {
Message msg = Message.obtain(handler, new Runnable() {
#Override
public void run() {
doOtherStuff();
}
});
msg.arg1 = constructedMessage.length();
msg.arg2 = -1;
msg.obj = constructedMessage;
Log.d(TAG, "Calling myMessenger.send()");
msg.sendToTarget();
Log.d(TAG, "Sent");
} catch (Exception e) {
e.printStackTrace();
}
The other way to do this using native means:
private static Messenger myMessenger = new Messenger(new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
// do something what you need
if (msg.getTarget() != null) {
msg.sendToTarget();
}
return false;
}
}));
try {
final Message msg = Message.obtain();
msg.setTarget(new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
doOtherStuff();
return false;
}
}));
msg.arg1 = constructedMessage.length();
msg.arg2 = -1;
msg.obj = constructedMessage;
Log.d(TAG, "Calling myMessenger.send()");
myMessenger.send(msg);
Log.d(TAG, "Sent");
} catch (final Exception e) {
e.printStackTrace();
}