Android NullPointerException being thrown in Synchronized Method - android

I have an android app written in java.
The app basically connects to a device which sends the app messages. The app waits for the messages to come in and then reports them, before processing each message.
I have a Connection class and a Listener class.
The Connection class is started via the constructor, which sets up the Listener class to listen for messages coming in from the device.
When a message comes in, the Listener sends the message to a method in the Connection class, reportMessage(). This is where the message is processed.
The Listener class is on a separate thread.
The code is shown below.
public class Connection
{
private String response;
private String newResponse;
private DataInputStream reader;
private DataOutputStream writer;
private Socket socket;
private boolean keepListening;
private Listener listener;
public Connection (String _ipAddress, int portNumber)
{
try
{
socket = new Socket(_ipAddress, _port); //Connect to the server and its socket
writer = new DataOutputStream(socket.getOutputStream()); //Connect to the server to receive and send messages
reader = new DataInputStream(socket.getInputStream());
listener = new Listener(reader, this); //Create a new listener for the client
new Thread(listener).start(); //Set the listener off running
}
catch (Exception e)
{
...
}
}
public synchronized void reportMessage(String message)
{
try
{
if("".equals(newResponse))
{
newResponse = new String();
}
newResponse = newResponse + message;
System.out.println("Message Received: " + newResponse);
processMessage(); //Process the message
}
catch (Exception e)
{
response = e.getCause().toString();
}
}
}
public class Listener implements Runnable
{
private DataInputStream reader = null;
private boolean keepListening;
private String serverMessage;
private Connection connection;
public Listener (DataInputStream inFromServer, Connection connection)
{
reader = inFromServer;
//Get the client connection's message transfer
keepListening = true;
this.connection = connection;
}
public void run()
{
while (keepListening)
{
try
{
if (reader.available() > 0)
{
byte[] readInData = new byte[reader.available()]; //Initialise the array
reader.read (readInData); //Read in the data
serverMessage = Utils.byteToString(readInData);
connection.reportMessage(serverMessage); //Report the message
}
}
catch (IOException e)
{
System.out.println("Error reading." + e.getLocalizedMessage().toString());
keepListening = false;
}
keepListening = connection.getKeepListening();
}
}
}
This works well for a time, then sometimes I receive an error which crashes the program.
When running in debug mode, I get a NullPointerException thrown on whatever is the first line of reportMessage() in the Connection class.
The program is suspended on whatever line is the first line, whether it is a System.out.println or a line of actual code.
And the error doesn't get caught by the try and catch. It crashes the program and there is no handling of the error even though it occurs in the try and catch.
This leads me to believe the error is not being thrown by anything in the reportMessage() method. If this is the case, then perhaps the error is being thrown in the Listener class .run().
However, I cannot see where any NullPointerException can be thrown from, as I have tried to make all the checks and when it is thrown, it is thrown when there are messages being sent.
The debugger says "An exception stack trace is not available".
The LogCat says:
08-21 10:35:57.894: E/AndroidRuntime(1118): FATAL EXCEPTION: Thread-12
08-21 10:35:57.894: E/AndroidRuntime(1118): java.lang.NullPointerException
08-21 10:35:57.894: E/AndroidRuntime(1118):atCom.que.wifiaudio.Connection.reportMessage(Connection.java:339)
08-21 10:35:57.894: E/AndroidRuntime(1118): at com.que.wifiaudio.Listener.reportIncomingMessage(Listener.java:93)
08-21 10:35:57.894: E/AndroidRuntime(1118): at com.que.wifiaudio.Listener.run(Listener.java:67)
08-21 10:35:57.894: E/AndroidRuntime(1118): at java.lang.Thread.run(Thread.java:1102)
Can anyone help me?
I need to know what is throwing the NullPointerException and how to stop it!

Turns out it was the
catch (Exception e)
{
response = e.getCause().toString();
}
The processData() method was throwing an exception which was being caught, but the Exception's cause was Null, which was throwing the error.

Related

Android Socket connects to server but doesn't write anything

I'm currently runing a server on Eclipse(local IP 192.168.1.255, listening to port 4567). A client can connect trought sockets and send messages, that will be printed on the terminal by the server.
Part of the server code is the following:
System.out.println("Client connected: " + clientName);
String line;
while (true){
line = in.nextLine();
System.out.println("STRING RECEIVED: " + line + " FROM " + clientName);
}
where in is the input stream of the client socket.
Part of client code, instead, is:
while(true) {
System.out.print("\nEnter your input: ");
line = stdin.next();
socketOut.println(line);
socketOut.flush();
}
So, in example, a possible output on server terminal with two clients connected is the following:
Client connected: Socket[addr=/192.168.1.225,port=54852,localport=4567]
STRING RECEIVED: Hello FROM Socket[addr=/192.168.1.225,port=54852,localport=4567]
STRING RECEIVED: World FROM Socket[addr=/192.168.1.225,port=54852,localport=4567]
Client connected: Socket[addr=/192.168.1.225,port=54945,localport=4567]
STRING RECEIVED: Hello2 FROM Socket[addr=/192.168.1.225,port=54945,localport=4567]
Everything works well, so i'm now trying to access server trough sockets on a simple app developed on Android Studio. The code is:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new BackgroundTask().execute();
}
private class BackgroundTask extends AsyncTask {
#Override
protected Object doInBackground(Object[] params) {
try {
Socket socket = new Socket("10.0.2.2", 4567);
PrintWriter out = new PrintWriter(socket.getOutputStream());
out.println(new String("Hi from Android!"));
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
}
But the output is just
Client connected: Socket[addr=/192.168.1.225,port=55001,localport=4567]
and nothing else.
Any advice about the println doesn't send anything? The program works perfectly on Eclipse on both client/server side, so i guess the problem is on Android. Also, i enabled the Android network permissions, so the connection should work.
Thanks in advance to everybody.
EDIT: solved, i just changed Android client code to:
try {
Socket socket = new Socket("10.0.2.2", 4567);
if (socket.isConnected()) {
PrintWriter out = new PrintWriter(new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream())), true);
String line = new String("Hi from Android!");
out.println(line);
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
You need to either flush the PrintWriter or construct it to auto-flush. It doesn't by default.

Android TCP Socket InputStrem Intermittent Read or too Slow

I need to implement a TCP comunication between an IoT device(custom) and an Android App.
For the Wifi device we have a Server Socket, while in Android i have an AsyncTask as a Client Socket. Both the device and the smarthone are connected to the same network.
Here is the Android Client Socket code for the initialization/socket-read and socket-write:
Variables:
static public Socket nsocket; //Network Socket
static public DataInputStream nis; //Network Input Stream
static private OutputStream nos; //Network Output Stream
AsyncTask method doInBackgroud:
#Override
protected Boolean doInBackground(Void... params) { //This runs on a different thread
boolean result = false;
try {
//Init/Create Socket
SocketInit(IP, PORT);
// Socket Manager
SocketUpdate();
} catch (IOException e) {
e.printStackTrace();
Log.i("AsyncTask", "doInBackground: IOException");
clearCmdInStack();
MainActivity.SocketDisconnectAndNetworkTaskRestart();
result = true;
} catch (Exception e) {
e.printStackTrace();
Log.i("AsyncTask", "doInBackground: Exception");
result = true;
} finally {
try {
SocketDisconnect();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
Log.i("AsyncTask", "doInBackground: Finished");
}
return result;
}
Socket Initializzation:
public void SocketInit(String ip, int port) throws IOException {
InetAddress addr = InetAddress.getByName(ip);
SocketAddress sockaddr = new InetSocketAddress(addr, port);
nsocket = new Socket();
nsocket.setReuseAddress(false);
nsocket.setTcpNoDelay(true);
nsocket.setKeepAlive(true);
nsocket.setSoTimeout(0);
nsocket.connect(sockaddr, 0);
StartInputStream();
StartOutputStream();
}
Read from Socket:
private void SocketUpdate() throws IOException, ClassNotFoundException {
int read = 0;
// If connected Start read
if (socketSingleton.isSocketConnected()) {
// Print "Connected!" to UI
setPublishType(Publish.CONNECTED);
publishProgress();
if(mConnectingProgressDialog != null)
mConnectingProgressDialog.dismiss(); //End Connecting Progress Dialog Bar
//Set Communications Up
setCommunicationsUp(true);
Log.i("AsyncTask", "doInBackground: Socket created, streams assigned");
Log.i("AsyncTask", "doInBackground: Waiting for inital data...");
byte[] buffer = new byte[3];
do{
nis.readFully(buffer, 0, 3);
setPublishType(Publish.READ);
publishProgress(buffer);
}while(!isCancelled());
SocketDisconnect();
}
}
Streams init:
public void StartInputStream() throws IOException{
nis = new DataInputStream(nsocket.getInputStream());
}
public void StartOutputStream() throws IOException{
nos = nsocket.getOutputStream();
}
Read and Write methods:
public int Read(byte[] b, int off, int len) throws IOException{
return nis.read(b, off, len); //This is blocking
}
public void Write(byte b[]) throws IOException {
nos.write(b);
nos.flush();
}
public boolean sendDataToNetwork(final String cmd)
{
if (isSocketConnected())
{
Log.i("AsyncTask", "SendDataToNetwork: Writing message to socket");
new Thread(new Runnable()
{
public void run()
{
try
{
Write(cmd.getBytes());
}
catch (Exception e)
{
e.printStackTrace();
Log.i("AsyncTask", "SendDataToNetwork: Message send failed. Caught an exception");
}
}
}).start();
return true;
}
Log.i("AsyncTask", "SendDataToNetwork: Cannot send message. Socket is closed");
return false;
}
The application is very simple, the android app sends a command(via sendDataToNetwork method) to the IoT device and the latter sends back an "ACK" Command string.
The problem
The problem is that while the IoT device always receives the command, the smartphone rarely gets the ACK back. Sometimes i get something like "ACKACKACKACK". By debugging the IoT device i'm sure that it successfully sends back the ACK, so the problem lies in the InputStream read() method which doesn't retrieve the string right away.
Is there a way to empty the InputStream buffer right away, so that i get an "ACK" string back from the IoT device every time i send a command?
Update
I've updated the socket config so that there are no more buffer limitations and i've replaced read() method with readFully. It greatly improved, but still make some mistakes. For istance one out of 2-3 times no ack is received and i get 2 ack the next turn. Is this perhaps the computational limit of the IoT device? Or is there still margin for a better approach?
the problem lies in the InputStream read() method which doesn't empty the buffer right away.
I don't know what 'empty the buffer' means here, but InputStream.read() is specified to return as soon as even one byte has been transferred.
Is there a way to empty the InputStream buffer right away, so that i get an "ACK" string back from the IoT device every time i send a command?
The actual problem is that you could be reading more than one ACK at a time. And there are others.
If you're trying to read exactly three bytes, you should be using DataInputStream.readFully() with a byte array of three bytes.
This will also get rid of the need for the following array copy.
You should not mess with the socket buffer sizes except to increase them. 20 and 700 are both ridiculously small values, and will not be the actual values used, as the platform can adjust the value supplied. Your claim that this improved things isn't credible.
You should not spin-loop while available() is zero. This is literally a waste of time. Your comment says you are blocked in the following read call. You aren't, although you should be. You are spinning here. Remove this.

Android Asynctask method does not display the data

I tried to display data(string) from android device to java desktop server application. I was successful in that. I tried to find wifi signal strength from wifi access point to android device. I did that too. Now, I need to integrate this both thing.
First, is the client code where I find the signal strength and pass it to server. First, I run the server. It runs and waits. As soon as I run the client the signal strength from 1st router is displayed and then the app crashes. I have given the error log.
It crashes because of Async method in the client. This Async task code works well when I try to send string from android mobile to java desktop server. But, here it gives me an error. I think, I have made some simple error.
Client.java
package com.example.temp;
public class MainActivity extends Activity {
private Socket client;
private PrintWriter printwriter;
private EditText textField;
private Button button;
private String messsage;
StringBuilder sb = new StringBuilder();
public final static String extra = "com.example.temp.MESSAGE";
protected static final long TIME_DELAY = 5000;
TextView mTextView;
Handler handler=new Handler();
int count =0; String data ="";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = (TextView) findViewById(R.id.text_id);
handler.post(updateTextRunnable);
messsage=mTextView.getText().toString();
new Asynctask().execute(messsage);
}
Runnable updateTextRunnable = new Runnable() {
public void run() {
if (count < 5) {
WifiManager mainWifiObj;
mainWifiObj = (WifiManager) getSystemService(Context.WIFI_SERVICE);
class WifiScanReceiver extends BroadcastReceiver {
public void onReceive(Context c, Intent intent) {
}
}
WifiScanReceiver wifiReciever = new WifiScanReceiver();
registerReceiver(wifiReciever, new IntentFilter(
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
List<ScanResult> wifiScanList = mainWifiObj.getScanResults();
for (ScanResult result : wifiScanList) {
if (result.SSID.equals("Dal-WPA2")) {
sb.append(result.level);
}
if (result.SSID.equals("eduroam")) {
sb.append(result.level);
}
if (result.SSID.equals("Dal")) {
sb.append(result.level);
}
}
count++; mTextView.setText("getting called " +count + sb);
} else {
}
//----------------code here to send values to java server---
handler.postDelayed(this, TIME_DELAY);
}
};
class Asynctask extends AsyncTask<String, Void, Void> {
private static final String IP_ADDRESS = "134.190.162.165";
private static final int DEST_PORT = 4444;
private EditText mTextField;
protected Void doInBackground(String... messages) {
// if (messages.length != 1) { return null; }
String message = messages[0];
Socket client = null;
try {
client = new Socket(IP_ADDRESS, DEST_PORT); // connect to server
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// Write to server.
try {
printwriter = new PrintWriter(client.getOutputStream(), true);
printwriter.write(messsage); // write the message to output stream
printwriter.flush();
printwriter.close();
}
catch (IOException e) {
e.printStackTrace();
} finally {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
}
The Error from the log cat I found is : It is in the Async task here.
>FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
android.os.AsyncTask$3.done(AsyncTask.java:278)
java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
java.util.concurrent.FutureTask.setException(FutureTask.java:124)
java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
java.util.concurrent.FutureTask.run(FutureTask.java:137)
android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.NullPointerException
com.example.temp.MainActivity$Asynctask.doInBackground(MainActivity.java:114)
com.example.temp.MainActivity$Asynctask.doInBackground(MainActivity.java:1)
android.os.AsyncTask$2.call(AsyncTask.java:264)
java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
Activity com.example.temp.MainActivity has leaked IntentReceiver com.example.temp.MainActivity $1$1WifiScanReceiver#41756998 that was originally registered here. Are you missing a call to unregisterReceiver()?
02-17 15:13:52.771: E/ActivityThread(25738): android.app.IntentReceiverLeaked: Activity com.example.temp.MainActivity has leaked IntentReceiver com.example.temp.MainActivity$1$1WifiScanReceiver#41756998 that was originally registered here. Are you missing a call to unregisterReceiver()?
android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:763)
android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:567)
android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1167)
android.app.ContextImpl.registerReceiver(ContextImpl.java:1154)
android.app.ContextImpl.registerReceiver(ContextImpl.java:1148)
android.content.ContextWrapper.registerReceiver(ContextWrapper.java:348)
com.example.temp.MainActivity$1.run(MainActivity.java:58)
android.os.Handler.handleCallback(Handler.java:605)
android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
android.app.ActivityThread.main(ActivityThread.java:4517)
java.lang.reflect.Method.invokeNative(Native Method)
java.lang.reflect.Method.invoke(Method.java:511)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:993)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:760)
at dalvik.system.NativeStart.main(Native Method)
The server just waits for the response and displays the data. With simple string it displays the data But here, the client crashes so, it is not possible. So, I assume that client code is perfect.
There is no compile time error only run time. In the run(), I call Async method and then do handler.postdelayed, so that code runs again after few second. But it runs correctly till Asynctask class is called In the Async task, it gives me error.
I am new. It would be great if someone can point out my mistake.
I tried but I am not getting what I should do. I think my logic is correct as individual parts are running. But dont know why async task is not running here.
Thank you in advance.
Edited : The print writer and other sockets closed.
Still getting the same error.
I have just used class Asynctask and not public class Asycntask, hope there wont be any problem in this.
I just understand from the log file that error is in asynctask background , but exactly the error is not understandable also.
I dont know where I am getting wrong.
Thanks for the help.
fdvkfdnvkkfdnb fdkvj nfdvnjfdknv fdvnfdvnkdfnv fdjkvnfdkjvnjkfdn
fdjvfdjkv fdvndfkjvn fdlvnkdfvn fdkvnfdnvk fdvknfdkvn
fdvklmfd fdkv flkk fdkvkfl fdkkklvklfdm flvmalsvmaslvv
dfvkfdlkv f lkfdv fdlkvmfdklvm fdvkfdklv dfklvlfdknvkfdnv
dfvknfdklvn dfkvfdkvn fdkvnfdkvn dfkkvnfdknv dfjkvnfdkjnv
My guess is that the problem arises because you are not properly closing client and printwriter. (You need to close all streams for the socket as well as the socket itself.) On repeated executions, the AsyncTask tries to open a new socket and eventually the OS runs out of resources for doing so because of this failure to close. The call to new Socket(...) throws an exception (which you catch) but then client remains null. Since you don't return after the exception, you then get a NullPointerException. My guess is that this NullPointerException is what's responsible for the app crash. (This really is just a guess; the info in the error you posted is quite sparse.)
Try this code instead:
public class Asynctask extends AsyncTask<String, Void, Void> {
private EditText mTextField;
protected Void doInBackground(String... messages) {
String message = messages[0];
Socket client = null;
try {
client = new Socket(IP_ADDRESS, DEST_PORT);
} catch (IOException e) {
e.printStackTrace();
return null;
}
try {
printwriter = new PrintWriter(client.getOutputStream(), true);
printwriter.write(messsage);
}
catch (IOException e) {
e.printStackTrace();
} finally {
if (printwriter != null) {
try {
printwriter.close();
} catch (IOException e) {
e.printStackTrace();
}
printwriter = null;
}
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}

Broadcasting with WiFi Direct in android

I am beginner in android programming. Am trying to broadcast messages on WiFiDirect using the following code:
public class FileTransferService extends IntentService {
public static final String host= "255.255.255.255";
InetAddress broadcastAddress = InetAddress.getByName(host);// Exception: Unknown host exception
int port = 8888;
protected void onHandleIntent(Intent intent) {
Log.d(WiFiDirectActivity.TAG,"m in 1");
Context context = getApplicationContext();
DatagramSocket socket;
try {
socket = new DatagramSocket(port);
socket.setBroadcast(true);
socket.connect(broadcastAddress, port);
String message = "Hello";
byte[] buffer = message.getBytes();
DatagramPacket packet = new DatagramPacket(
buffer, buffer.length, broadcastAddress, port);
socket.send(packet); // <----- Causes a SocketException
} catch (IOException e) {
Log.d(WiFiDirectActivity.TAG, e.getMessage(), e);
}
}
}
It shows me unknown host exception on getByName() method. Is there anyway to replace the method? Am I going on a right path? Do I need to add anything along with this to send messages.
Thanks in advance
Try calling public UnknownHostException (String detailMessage) to get the detailed exception message.
Another way to call getByName() can be get from here
Below link has a step by step illustration of setting up a Wi-Fi Direct broadcaster
Connecting with Wi-Fi Direct

AsyncTask creation causes crash

Having some issues with a custom class that extends AsyncTask. My app is Targeting Android 4.0.3 and the below code works fine for 30+ people testing it. However there are two users that are seeing the app crash when I call new AsyncRequest like below.
I've got a working logger that is recording to a text file on the users storage and doesn't record the entry that is in the AsyncRequest constructor. So I have to assume that the crash is happening before the constructor is called.
One of the two devices that are experiencing this crash is running Android 4.0.4 apparently. Not sure what the other device is running. Unfortunately I dont' have access to the two devices so can't see a logcat output.
Any input as to why the object creation is causing a crash would be greatly appreciated.
String url = "www.google.com";
new AsyncRequest(callback, context).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url);
And here is the full AsyncRequest class
public class AsyncRequest extends AsyncTask<String, String, String>{
HttpURLConnection connection;
InputStream inStream;
IApiCallback callback;
Context context_;
public AsyncRequest(IApiCallback callback, Context context) {
// Log entry added for testing. Never gets called.
FileLogger.getFileLogger(context).ReportInfo("Enter AsyncRequest Constructor");
this.callback = callback;
context_ = context;
}
#Override
protected String doInBackground(String... uri) {
try {
URL url = new URL(uri[0] + "?format=json");
FileLogger.getFileLogger(context_).ReportInfo("Async Request: Sending HTTP GET to " + url);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.addRequestProperty("Accept-Encoding", "gzip");
connection.addRequestProperty("Cache-Control", "no-cache");
connection.connect();
String encoding = connection.getContentEncoding();
// Determine if the stream is compressed and uncompress it if needed.
if (encoding != null && encoding.equalsIgnoreCase("gzip")) {
inStream = new GZIPInputStream(connection.getInputStream());
} else {
inStream = connection.getInputStream();
}
if (inStream != null) {
// process response
BufferedReader br = new BufferedReader(new InputStreamReader(inStream));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
return sb.toString();
}
} catch (SocketTimeoutException e) {
FileLogger.getFileLogger(context_).ReportException("Async Request: SocketTimeoutException", e);
Log.i("AsyncRequest", "Socket Timeout occured");
} catch (MalformedURLException e) {
FileLogger.getFileLogger(context_).ReportException("Async Request: MalformedUrlException", e);
} catch (IOException e) {
FileLogger.getFileLogger(context_).ReportException("Async Request: IOException", e);
Log.i("doInBackground:","IOException");
if (e != null && e.getMessage() != null) {
Log.i("doInBackground:",e.getMessage());
}
} catch (Exception e) {
FileLogger.getFileLogger(context_).ReportException("Async Request: Exception", e);
} finally {
if (connection != null)
connection.disconnect();
}
return null;
}
#Override
protected void onPostExecute(String result) {
if (result != null)
FileLogger.getFileLogger(context_).ReportInfo("Async Request: Response is valid");
else
FileLogger.getFileLogger(context_).ReportInfo("Async Request: Invalid response");
callback.Execute(result);
}
}
EDIT: As per comments below.
Here is the full method that I call my custom AsyncTask from. All the logging messages I have up to creating the AsyncTask are showing in the log. None of the exceptions are.
The logging displays the url value just before creating my AsyncRequest and the URL is not malformed at all. It's what I'm expecting.
public void GetServerInfoAsync(IApiCallback callback, Context context) throws IllegalArgumentException, Exception {
if (callback == null)
throw new IllegalArgumentException("callback");
if (context == null)
throw new IllegalArgumentException("context");
try {
FileLogger.getFileLogger(context).ReportInfo("Build URL");
String url = GetApiUrl("System/Info");
FileLogger.getFileLogger(context).ReportInfo("Finished building URL");
if (url != null) {
FileLogger.getFileLogger(context).ReportInfo("GetServerInfoAsync: url is " + url);
new AsyncRequest(callback, context).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url);
} else {
FileLogger.getFileLogger(context).ReportError("GetServerInfoAsync: url is null");
}
} catch (IllegalArgumentException iae) {
FileLogger.getFileLogger(context).ReportException("GetServerInfoAsync: IllegalArgumentException", iae);
throw iae;
} catch (Exception e) {
FileLogger.getFileLogger(context).ReportException("GetServerInfoAsync: Exception", e);
throw e;
}
}
First of all, just keep in mind that executeOnExecutor() is not available prior to Api 11. You have already said the issue is with a 4.0.4 device, but just keep this in mind.
Here are the steps I would take in order to troubleshoot what the problem is. It seems as if you have already done a few of these with all those ReportInfo() statements.
First, I assume your call to GetServerInfoAsync is within a try...catch, correct? I am checking because of your use of Throw. Also, you have already added logging to check for errors with the url. Since the errors occur before you actually use it, the error cannot be with the url, or any internet permissions.
You call the AsyncTask generation with references to callback and context. You have added logging via ReportInfo() which references context, and those work, yes? Therefore, context is not your issue. However, you never check what callback is. You throw an error if it is null, but you never do anything with it before you call AsyncRequest. Try a ReportInfo(callback.toString()) to see what it is.
If all else fails, it would seem to be an error with threading. Why not try using just AsyncTask, instead of executeOnExecutor(). Do you really need more than 1 background thread?
Sorry for not getting back to this sooner. There were numerous issues here.
First off... Thanks to Wolfram's suggestion I was able to catch the exception and diagnose that the issue was that my FileLogger (and another class) was a static reference and these two tablets couldn't find the reference at runtime. So I ended up removing Logging from my async methods.
Secondly, after making the above changes there was another issue which was that a looper had to be called from the main thread. It turned out that these two tablets weren't calling my async task from the main thread. So I had to enclose the async call in a new Handler using the MainLooper.

Categories

Resources