So this is the weirdest thing ever to happen to me during programing. Yes I'm no pro at programing, but I'm learning as I go. I've got an app talking to a server, a socket in the main thread, reading is done in a separate class and thread and writing in a separate class with asynctask.
The problem is LocationManager. I could talk to server and write/read commands just fine, I implemented the LocationManager and its listener.
I then proceeded to implement a method to update my textview with the new coordinates on locatinChanged. So far so good. Thing is when I use the Emulator control in eclipse and send coordinates the app crashed with a stringOutOfBoundsException (I've programed for 3 years now never seen this). I looked at the code stepped through it and so on. Read the stacktrace, logcat, console and everywhere I could think of but it got me nowhere. Until I finally went to the readerthread which looks like this:
public class ReaderThread extends Thread {
public void run() {
new Thread(new Runnable(){
public void run(){
try {
//Establish a bufferedreader to read from the socket/server.
in = new BufferedReader(new InputStreamReader(socket.getInputStream()), 8 * 1024);
}
catch(Exception e) { e.printStackTrace(); }
//As long as connect is true.
while (connected) {
String line;
try {
//Try to read a line from the reader.
line = in.readLine();
System.out.println(in.readLine());
if (in == null) {
//No one has sent a message yet.
System.out.println("No data recieved");
}
else {
int i = 0;
//As long as someone is sending messages.
while((line = in.readLine()) != null ){
//Make a new Message.
Message msg;
msg = new Message();
//Set the object to the input line.
msg.obj = line;
//Set an id so it can be identified in the main class and used in a switch.
msg.what = i;
System.out.println("i is: "+i);
//Send the message to the handler.
Main.this.h.sendMessage(msg);
}
}
}
catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}).start();
}
The variable i is in an if statement depending on what the server sent but I cut that out as it has nothing to do with this problem.
The problem is the freaking catch. When the catch is IOException, the app crashes. Out of dumb luck I changed this to Exception and printed e.message to catch the error and see what caused it. Thing is this change fixed it. How can switching IOException to just plain Exception fix a problem like this?
Its like with IOException the program says: "hey your not gonna catch the error but there is no error" but with Exception it says "Well now you could catch it so I'll proceed".
My app is working but I just can't grasp this, why and how does this happen?
You're essentially telling the application to catch the base Exception class. This means that any type of error will be caught, since all exception classes descend from that base type. Since StringOutOfBoundsException does not descend from IOException it was not being caught before and the error was not being caught. Instead of catching all exceptions, you might try the following:
try {
// Your code here...
} catch (IOException e) {
Log.e(TAG, "Caught an IOException!", e);
} catch (StringOutOfBoundsException e) {
Log.e(TAG, "Caught a string out of bounds Exception!", e);
}
I'm unable to determine what is actually throwing the StringOutOfBoundsException to begin with. It may be in the if statement that you cut out of your example.
while (connected) {
String line;
try {
//Try to read a line from the reader.
line = in.readLine();
System.out.println(in.readLine());
if (in == null) {
//No one has sent a message yet.
System.out.println("No data recieved");
}
The test for in == null is in a funny location. You should receive a NullPointerException if that test were to ever return true by nature of calling methods on it a few lines earlier. Obviously something is a little funny with this code.
You fail to save the return value from in.readLine() the second time you call it. I hope it did not contain anything useful. (Though, since you print the line, you obviously wanted to know what data it contained.)
Whatever that line was (from the first call to in.readLine()), it gets thrown away; there's nothing else in the loop that uses it before it is over-written on this line:
while((line = in.readLine()) != null ){
At this point, the two lines that you read are gone forever.
I'm not entirely sure what should be done to fix this; if it were me, I'd be sorely tempted to start over with a sheet of paper and sketch out what the method should be doing without looking at the existing code, then compare the sketch against the code to see which cases each one has overlooked.
Related
this issue is driving me a little crazy so hopefully one of you fine people could point me in the right direction. I am attempting to prepare a JSONObject that will be passed from client to server. The following is the problematic method stripped down to its essentials:
private JSONObject getJsonParam(int id)
{
JSONObject param = new JSONObject();
try
{
param.put("functionCode", 50);
param.put("id", id);
return param;
}
catch (JSONException e)
{
e.printStackTrace();
}
catch (Throwable e)
{
e.printStackTrace();
}
return null;
}
I have carefully traced the code in debug mode. In the actual method, I put many more paramters in the JSONObject and all is well until the last param.put() method where I attempt to insert the id. When this is the current execution line, I can visualize the param variable and all looks good. Then when I perform the step function to execute the last param.put call, it jumps to the return null statement. I have put breakpoints in both catch blocks and neither are being executed it seems. (I added the second catch block to make sure no other throwable was causing issues).
Any ideas what would be causing this odd behavior? I even tried rearranging the order of the put calls. It does not have any issue with a particular put call, but just the last one before the return statement.
I am working in Android/Java.
The code is not causing an error - you are merely being caught out by the fact that the compiler has optimized both return statements to use the same code.
In each case the return is of some "current value", in one case the current value comes from the param variable, in the other case it is null. Since the compiler uses just one copy of the code, the debugger is unable to determine correctly which actual line of source is being executed.
I am trying to perform a simple get request using Apache HTTPClient however it seems as if all the code after the HTTPResponse response = client.execute(get); is being skipped. I am not able to access the contents of the response object,they are all null. However when I use debug mode and I explore the object I see all the data. This function is wrapped in an async task so I am wondering the task itself is not waiting on it to be executed or something I am not sure.
Something similar happened here:
Android code after httpclient.execute(httpget) doesn't get run in try (using AsyncTask)
Here is the code.
#Override
public T execute()
{
utils = new GeneralUtils();
if(getURL() == null)
{
throw new NullPointerException("No path specified");
}
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(getURL());
Log.e(TAG,"client created");
if(getHeaders()!=null)
{
Log.e(TAG,"client created");
for(Map.Entry<String,String> header:getHeaders().entrySet())
{
get.addHeader(header.getKey(),header.getValue());
}
}
try
{
HttpResponse response = client.execute(get);
Log.e(TAG,"executed");
if(response==null)
Log.v(TAG,"its null as heell");
Log.v(TAG,response.getStatusLine().getReasonPhrase());
Log.v(TAG,String.valueOf(response.getStatusLine().getStatusCode()));
Log.e(TAG,getURL());
Log.v(TAG,"everything else is dead");
for(Header header:response.getAllHeaders())
{
Log.v(TAG,header.getName()+" "+header.getValue());
}
if(response.getStatusLine().getStatusCode() == 200)
{
if(response.getEntity().getContent()!=null)
{
try
{
if(utils.isExternalStorageWritable())
{
String path = getContext().getFilesDir().getAbsolutePath()+"/"+getFileCategory()+"/" +getAlarmId()+getFileExtension();
media = new File(path);
/**
* if the directory has not being created this function does the creation.
*/
media.mkdirs();
FileOutputStream fileOutputStream = new FileOutputStream(media);
IOUtils.copy(response.getEntity().getContent(),fileOutputStream);
fileOutputStream.close();
Log.e(TAG,media.getAbsolutePath());
return (T)media;
}
return null;
}
catch (ClientProtocolException e)
{
Log.v(TAG,e.getMessage());
}
catch (IOException e)
{
Log.v(TAG,e.getMessage());
}
}
}
}
catch (IOException e)
{
Log.e(TAG, e.getCause().getMessage());
e.printStackTrace();
}
return null;
}
The code is not throwing any exceptions so I am not sure about what's happening.
All the code after the response object does not work. It just returns null, As in as soon as I try to obtain a value from response like so response.getStatusCode(), it seems as if the code goes dead and just returns null.
Why don't you use a library that will handle all these restful connections?
I would recommend a couple:
https://github.com/darko1002001/android-rest-client (this is mine i have to mention it first :). I have built this library for the projects i build. For your case you would supply a parser which will give you an InputStream which you will just save as a file (as you do it now with IO utils). It handles the Asynchronous part of the whole thing and generally gives you a nice way to organize code.
http://square.github.io/retrofit/ - is another one that i have been playing around with. i think it is pretty well made and should be able to do whatever you want with it.
http://java.dzone.com/articles/android-%E2%80%93-volley-library - Volley is a project that came out straight from Google and it was demoed at the last Google IO conference. It handles all the async operations for you as well and enables you to do all these things. One thing that i am not really sure about is whether or not it will enable you to parse the responses in the background thread.
I would strongly suggest for you to use one of these as they might save you a lot of time.
If you do want to continue with your code then i would suggest to first investigate if some of the "if" blocks you have are skipped, use the debugger or add log messages to see if it enters the blocks. Go step by step and see what goes wrong.
I am doing something similar in my project, check out this file:
https://github.com/darko1002001/android-rest-client/blob/master/android-rest-lib/src/main/java/com/dg/libs/rest/client/BaseRestClient.java
I'm developing an Android real-time-data app that sends data (floats and ints) to a server on the local subnet via a TCP socket. The problem I'm facing is that after sending some data simultaneously the socket doesn't send anymore data at all. I debugged the app and it shows that data is being sent but doesn't show up on the server. After this happens if I close the connection the server doesn't even get the notification that the connection has been terminated which it should according to my design model. Meanwhile I get an exception on the app saying it can not write to a broken pipe. This tells me that the problem is with the app because I also did test using a desktop app and I can send huge amounts of data to the server and it gets delivered.
And please keep in mind that the data size I'm talking about here is 252 bytes per packet.
Here's my class I'm using. (This runs in an AsyncTask object )
public class Network
{
private Socket handle;
public static enum TASK
{
TASK_CONNECT, TASK_SEND, TASK_CLOSE
}
public Network()
{
}
public String lastError = "";
public boolean Connect(String host, int port)
{
try
{
lastError = "Connecting to server.";
handle = new Socket(host, port);
handle.setTcpNoDelay(true); //
handle.setSendBufferSize(SIZE_OF_PACKET); ///==> These don't seem to help at all
handle.setKeepAlive(true); ///
return true;
}catch(IOException e)
{
lastError += e.getMessage() != null ? " "+ e.getMessage() : "";
return false;
}
}
private void err(String e){
System.err.println(e);
}
private boolean SendPacket(byte buffer[])
{
OutputStream oStream = null;
err("sending: " + buffer.length + " bytes");
try
{
lastError = "Obtaining output stream.";
oStream = handle.getOutputStream();
lastError = "Error sending data.";
oStream.write(buffer);
oStream.flush();
return true;
}catch(Exception e)
{
lastError += e.getMessage() != null ? " "+ e.getMessage() : "";
}
return false;
}
public void Close()
{
try{ handle.close(); handle = null; }catch(Exception e){} // swallow exception
}
}
I send my data in a loop depending on how many numbers I have. I tried a Google search but didn't find anything relevant. Has anyone experienced this before? It's making me mad now.
EDIT: Wireshark shows incoming "red" packets that don't reach the desktop app (server)
Look at this picture.
You can see the first few have Len > 0 the red ones have 0.
I think it's time Google interfaced the USB so we can use it. At least that'd would have been my first option.
Should you not be calling oStream.close() after you flush the stream, given that you never use it again?
Also, you say that this is being run in an AsyncTask object. Is it possible that multiple threads could be attempting to send packets at the same time? If so, you might need some form of synchronisation around the SendPacket method.
Ok. I solved the issue by using UDP instead. Thank you all.
But I still didn't find the source of the problem.
Im having some trouble reading/writing to a tcp server for which im building an app. In a recent thread I was suggested to use a service instead but this is a project for school which suggested asyncTask so I might aswell go for that.
So the classes ive got are my activity class and async, nothing interesting is going on in activity but sending a string which is working so ill get on with the async one.
class ServerTask extends AsyncTask<Void, Void, Void>{
public static String ip = "10.0.2.2";
public static int port = 2002;
Socket socket;
public DataInputStream dis;
public DataOutputStream dos;
public String message;
#Override
protected Void doInBackground(Void... params) {
try {
socket = new Socket(ip, port);
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
} catch (Exception e) {
Log.i("AsyncTank", "Cannot create Socket");
}
while(socket.isConnected()){
read();
}
}
}
return null;
}
public void write(String message) {
try {
if (socket.isConnected()){
dos.writeUTF(message);
dos.flush();
} else {
Log.i("AsynkTask", "Socket appears to be closed");
}
} catch (Exception e) {
Log.i("AsynkTask", "Writing failed");
}
}
public String read() {
try {
if (socket.isConnected()) {
message = dis.readLine();
} else {
Log.i("AsyncTask", "Cannot read");
}
} catch (Exception e) {
Log.i("AsyncTask", "Cannot read from stream");
}
return message;
}
}
Things I do know, the server DOES get the messages but it doesnt update until I restart the server which leads me to believe that im not pushing a new line or something which makes it all appear as one line after its closed. This however might aswell be the server for which im not reponsible so ill have to read up in that.
The read part however does not want to work, im not sure on how to call the method to have it constantly listen and react to the servers sockt? I tried make a thread just before the return in doInBackGround but then the application starts works for a couple of seconds the force closes due to lack of memory? Do I need a thread to keep constantly listen?
The whole point of this as you might guess is to make a chat so the read method is eventually supposed to update a textView in my activity class. The send method is "working" but not as it should though this might be as I said earlier the server doing some funky buisness.
Another one, is it even possible to have the read as a method like I have or does something have to react when the server sends data and then call the method?
Edit
I have now moved the read part, or atleast some of it to doInBackGround so its now
dis = new BufferedReader(new InputStreamReader(socket.getInputStream()));
message = dis.readLine();
Log.i("AsynkTask", "Read : "+message+" this is doInBackGround!");
This along with a change to simply hardcode a printline in the server made me read that line in the client so im guessing its working realtively good for now.
How is it looking? Is it utter crap this code and should be done some other way? Got my functionality but never bad to learn to do it better so to speak :).
You should do both your writing and reading to the Socket in an AsyncTask's doInBackground() method, as both take time and could block the main (UI) thread. I don't know how you are calling your write() method above but you might also want to take a look at this question that might be related.
I've been working with Eclipse ADT for about 2 months. In that time, I have a small utility that allows me to select an IP Address and Port, and then send a file to that combo. The utility works as intended, but when I type in the wrong file name, the application hangs.
#Override
public void run() {
if (data != null) {
this.send(data);
} else if (this.file != null) {
if (file.exists()) {
this.send(file);
} else {
transferError = new FileNotFoundException("The specified file could not be found");
}
}
}
I've even tried to do the following in hopes that one or the other would throw, but I am unsuccessful in both.
public void run() {
if (data != null) {
this.send(data);
} else if (this.file != null) {
if (file.exists()) {
this.send(file);
} else {
transferError = new FileNotFoundException("The specified file could not be found");
}
}try {
throw new Exception("blah blah blah");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I've jockeyed around the exception, I've added the one above, I've tried placing it in different places, and all unsuccessful. Again, I'm exceptionally new to this, and got here from basically mincing various tcp client codes. Aside of creating a way to throw the exception correctly, please help me understand why the first one isn't working and why the one you suggest is.
in your else block you aren't throwin the transferError you create.
throw transferError;
However you probably won't be able to do that because FileNotFoundException is a checked exception and the run() method doesn't declare any thrown exceptions. You probably need to find a different way to present the error to the user, like with a Toast or something.
Your second block doesn't work because you are catching the exception you throw.