JsonReader running in thread crashes app - java

My app is crashing unpredictably and I don't understand why. I'm using HttpURLConnection to retrieve a json file and I'm trying to use the JsonReader class to read from, and use that file. The trouble is that the application crashes after reading or doing anything to the instance of JsonReader.
I've read the input stream with scanner but that causes a similar problem. However when reading with the scanner I can print small amounts of json from the server. So the data from the server is probably making it into the JsonReader as well.
This is my code:
public class ConnectToServer implements Runnable {
private URL connectionUrl;
private MainActivity output;
public ConnectToServer(URL url, MainActivity mainActivity) {
connectionUrl = url;
output = mainActivity;
}
public void printError(String errorMessage){
output.output(errorMessage);
}
public InputStream GetInputStream(){
try {
HttpURLConnection connection = (HttpURLConnection)connectionUrl.openConnection();
InputStream inputStream = new BufferedInputStream(connection.getInputStream());
if (inputStream == null){
printError("Input stream is null");
}
return inputStream;
} catch (IOException ex){
printError("IO exception has been thrown");
} catch (Exception ex){
printError("Normal exception thrown: " + ex.getClass().getSimpleName());
}
return null;
}
#Override
public void run() {
InputStream inputStream = GetInputStream();
try {
if (inputStream == null){
printError("Input stream not initiated");
} else {
JsonReader reader = new JsonReader(new InputStreamReader(inputStream, "UTF-8"));
printError(reader.toString());
reader.close();
}
} catch (Exception ex){
printError("Exception while printing input stream: " + ex.getClass().getSimpleName());
}
printError("Thread finished");
}
This gets run on a thread created in the main UI thread.
public void connect(){
output("connect started");
boolean success = true;
try {
URL url = new URL("http://geonews.azurewebsites.net/api/Location");
serverConnection = new ConnectToServer(url,this);
Thread thread = new Thread(serverConnection);
thread.start();
} catch (MalformedURLException ex){
output("Messed up the URL");
success = false;
}
if (success){
output("Thread has been started");
} else {
output("exception was thrown while trying to run thread");
}
}
Does anybody know why this code would be causing my app to crash? Even if it gets to "Thread finished" it will crash soon after.
Btw I realise I should be using AsyncTask but I've already gone down this track and I'd rather get this going first.
Logcat:
06-14 22:45:00.058 4032-4052/com.tomsapps.thomas.jsonreadertestapp E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-314
Process: com.tomsapps.thomas.jsonreadertestapp, PID: 4032
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6247)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:867)
at android.view.View.requestLayout(View.java:17364)
at android.view.View.requestLayout(View.java:17364)
at android.view.View.requestLayout(View.java:17364)
at android.view.View.requestLayout(View.java:17364)
at android.view.View.requestLayout(View.java:17364)
at android.view.View.requestLayout(View.java:17364)
at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:360)
at android.view.View.requestLayout(View.java:17364)
at android.widget.TextView.checkForResize(TextView.java:6798)
at android.widget.TextView.updateAfterEdit(TextView.java:7693)
at android.widget.TextView.handleTextChanged(TextView.java:7709)
at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:9440)
at android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:964)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:515)
at android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:272)
at android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:33)
at android.widget.TextView.append(TextView.java:3616)
at android.widget.TextView.append(TextView.java:3603)
at com.tomsapps.thomas.jsonreadertestapp.MainActivity.output(MainActivity.java:63)
at com.tomsapps.thomas.jsonreadertestapp.ConnectToServer.printError(ConnectToServer.java:26)
at com.tomsapps.thomas.jsonreadertestapp.ConnectToServer.run(ConnectToServer.java:74)
at java.lang.Thread.run(Thread.java:818)

I believe your output method from MainActivity modifies a TextView, therefore triggering the exception.
A view hierarchy can only be changed from the "Main" thread, in this case, you might want to try looking into runOnUiThread , some resources on StackOverflow :
how to use runOnUiThread
Android runOnUiThread explanation
Android Java runOnUiThread()
Hope this helps, good luck :)
Edit :
You might also want to use android Log instead of using TextView to display the errors.

Related

Malformed PDF print doesn't catch RuntimeException

I try to print a PDF file and it works fine until I try to print a malformed PDF file.
I don't know why the application crashes even though I used try / catch to prevent crashes. I checked and found out that PrintManager.java:1101 throws RuntimeException:
case MSG_ON_KILL: {
if (DEBUG) {
Log.i(LOG_TAG, "onKill()");
}
String reason = (String) message.obj;
throw new RuntimeException(reason);
}
so code below shouldn't lead to crash:
public static void startPdfPrintProcedure(#NonNull Context context, #NonNull String filePath, #Nullable String jobName) {
try {
PrintManager printManager = (PrintManager) context.getSystemService(Context.PRINT_SERVICE);
String jobName = formatDefaultJobName(context.getResources(), jobName);
PrintDocumentAdapter pda = new SimplePrintDocumentAdapter(new File(filePath));
if (printManager != null) {
try {
printManager.print(jobName, pda, null); // <- crash here even though there is a try/catch
} catch (RuntimeException e) {
showUnknownError();
}
} else {
showUnknownError();
}
} catch (RuntimeException e) {
showUnknownError();
}
}
Exception that I get after try to print PDF. :
java.lang.RuntimeException: Cannot print a malformed PDF file
at android.print.PrintManager$PrintDocumentAdapterDelegate$MyHandler.handleMessage(PrintManager.java:1101)
at android.os.Handler.dispatchMessage(Handler.java:112)
at android.os.Looper.loop(Looper.java:216)
at android.app.ActivityThread.main(ActivityThread.java:7625)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
Why try/catch code doesn't catch this exception? How can I secure this piece of code from crashing?
This happens because some "Genius" Google developer has come up with the "Great" idea of throwing an exception in the main thread causing your application to close.
I have tried to solve the problem using reflection but the implementation is too closed.
Unfortunately, you have to use it assuming the imminent closure of your application in case of incorrect files, unless you want to implement a library to check the PDF format before calling the API.
Google never fails, you always have to mess around with its implementation.
The secondary thread ends up calling this handler.
private final class MyHandler extends Handler {
public static final int MSG_ON_KILL = 5;
...
#Override
public void handleMessage(Message message) {
switch (message.what) {
...
case MSG_ON_KILL: {
if (DEBUG) {
Log.i(LOG_TAG, "onKill()");
}
String reason = (String) message.obj;
throw new RuntimeException(reason);<---------
}
default: {
throw new IllegalArgumentException("Unknown message: "
+ message.what);
}
}
}
}
One way is to check if PDF file is corrupted or not by using PDF viewer library : https://github.com/voghDev/PdfViewPager
import library : implementation 'es.voghdev.pdfviewpager:library:1.1.2'
Use below code to check if PDF file is corrupted
BasePDFPagerAdapter adapter;
PDFViewPager pdfViewPager;
pdfViewPager = findViewById(R.id.pdfViewPager);
adapter = new PDFPagerAdapter(this, path, new PdfErrorHandler() {
#Override
public void onPdfError(Throwable t) {
Log.d("pdfcorrupt",">> yes");
isPDFCorrupted = true;
}
});
pdfViewPager.setAdapter(adapter);
When PDF file is not valid, onPdfError() method will be called.
If your file is corrupted, simply do not allow to print.

Connecting to localhost from Android Emulator [duplicate]

This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
Closed 8 years ago.
I know this question has been asked a lot on SO already so I apologize if it is redundant, but I can't seem to find an answer to my specific problem anywhere.
I'm attempting to connect my Android emulator to a localhost. Here is my connection code:
public void readPHP(String filename) throws IOException {
url = new URL("http://10.0.2.2:8000/" + filename);
URLConnection conn = url.openConnection();
InputStream stream = null;
try {
stream = conn.getInputStream();
} catch (IOException e) {
System.out.println(e.getMessage());
}
// more code....
stream.close();
}
I've also added the following line to my manifesto:
<uses-permission android:name="android.permission.INTERNET"/>
The app installs properly with no error messages but when I try to run it from the phone, it crashes with the vague message "Unfortunately, CodeGlass GDK has stopped." I'm sure this is a problem with Android because when I try to run the same code in a simple Java program it works as expected.
You are opening a connection in your UI Thread, which is causing an NetworkOnMainThreadException . Just put your code inside an AsyncTask, inside doInBackground() method, like this:
public class MyAsyncTask extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(String fileName) {
url = new URL("http://10.0.2.2:8000/" + filename);
URLConnection conn = url.openConnection();
InputStream stream = null;
try {
stream = conn.getInputStream();
} catch (IOException e) {
System.out.println(e.getMessage());
}
// more code....
stream.close();
return null;
}
}
You must use asynctask to get the data from url like they said.
But there is another way. İt is not advisable normally, but if you want to move on for now and get back and properly write an asynctask, you can use this piece of code for now;
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Hope this helps.

why run and start call simultaneously in java

I am learning a tutorial about how to consume json web service.
But I have two doubts can you please help me in understanding.
I am learning from this link
http://codeoncloud.blogspot.in/2013/05/blackberry-java-json-tutorial.html
Here is one class extend by thread
public class ConnectJson extends Thread {
private String url;
public String response;
private String myinterface = ";interface=wifi";
public void run() {
HttpConnection conn = null;
InputStream in = null;
int code;
try {
conn = (HttpConnection) Connector.open(this.url + this.myinterface, Connector.READ);
conn.setRequestMethod(HttpConnection.GET);
code = conn.getResponseCode();
if (code == HttpConnection.HTTP_OK) {
in = conn.openInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[in.available()];
int len = 0;
while (-1 != (len = in.read(buffer))) {
out.write(buffer);
}
out.flush();
this.response = new String(out.toByteArray());
if (out != null){
out.close();
}
if (in != null){
in.close();
}
if (conn != null){
conn.close();
}
}
} catch (Exception e) {
Dialog.inform(e.toString());
}
}
public String jsonResult(String url){
this.url = url;
this.start();
this.run();
return response;
}
}
It is making one object of that class and call method of that class .In that method it call start as well as run method why ?
this.start();
this.run();?
In that method it call start as well as run method why ?
You'd have to ask the author of the code; looking at that class's code, it looks incorrect. It's also fairly unusual.
In the normal course of things, you don't call run directly; you start the thread (with start) and the JVM is then responsible for creating a new thread and calling run on it.
You can call run yourself if you really want that code to run right away on the current thread, but it's unusual and that class doesn't immediately look like it's designed to do that correctly. What that code actually does is start a new thread (which means run will eventually get called on that new thread), but then as you observed it also calls run directly. So run will run twice, and may well run twice simultaneously. Since the code in run uses instances variables that will be used by both threads but doesn't do anything to coordinate access to those instance variables...well, again, it looks incorrect.
I don't think I'd keep following that tutorial. You may find the Concurrency trail in the Java tutorials from Oracle might be useful. (Threads are part of it.)

Can't get html source code

I'm trying to get the HTML source code from a url and then pass it in to a string.
After I press the debug button it asks me if I want to open the debuger (the code compile fine.)
The debuger: ActivityThread.performLaunchActivity(ActivityThread$ActivityClientRecord, Intent) line: 2180
says e > cause > "java.lang.NullPointerException" and "detailMessage null".
So I understands that this is a NullPointerException but cant see where.
Amd the only thing the LogCat says is:
08-14 00:34:10.437: E/Trace(1784): error opening trace file: No such file or directory (2)
08-14 00:34:10.437: I/System.out(1784): Sending WAIT chunk
08-14 00:34:10.437: I/dalvikvm(1784): Debugger is active
08-14 00:34:10.644: I/System.out(1784): Debugger has connected
08-14 00:34:10.644: I/System.out(1784): waiting for debugger to settle...
08-14 00:34:11.867: I/System.out(1784): debugger has settled (1300)
08-14 00:34:13.428: D/dalvikvm(1784): threadid=1: still suspended after undo (sc=1 dc=1)
I don't really know what more info to give you. :/
The code I use for this is (this is the GetCode class)
public String html;
public void getSourceCode() throws ClientProtocolException, IOException {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet("http://www.novasoftware.se/webviewer/(S(pisjjgujku50by55lpbdl1a2))/design1.aspx?schoolid=18200&code=83310");
HttpResponse response = client.execute(request);
html = "";
InputStream in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder str = new StringBuilder();
String line = null;
while((line = reader.readLine()) != null)
{
str.append(line);
}
in.close();
html = str.toString();
System.out.println("html");
}
Then in the main class I just try to print the code.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
doStuff();
}
private void doStuff() {
try {
getcode.getSourceCode();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(getcode.html);
}
Firstly, you are still not providing enough information for an accurate diagnosis. You should supply:
a complete and accurate description of what is happening
the complete stacktrace for the exception, including the line numbers
all of the code that "connects the dots"; e.g. when and where is getSourceCode called.
Having said that, I can see two possible causes of NPE's in the (partial) code you have provided:
If getSourceCode() is not called, then the html variable could be null when the onCreate method is called.
If the Response object returned by client.execute(request) is an error response (i.e. the status is a 4xx or 5xx response code), then response.getEntity() will return null. I think this can also happen if the response has no content.

errors when using the bluetooth sample code on android developer site

I am working to add Bluetooth capabilities to my app and ultimately the device that I want to use is a headset/earpiece. I have begun assembling the code and I partial functionality with it. When I got to the code for setting up a bluetooth connection by server, I got errors when adding the code. I have tried solving the problems through the hover over the error and autocorrect but every time I fix one problem a different on arises. This leads me to believe that I am missing something that autocorrect doesn't know about. I need some help fixing the errors. Useful suggestions for setting a bluetooth codin for the first time would also be appreciated. Errors are surrounded with ||#| xxx |||. Error 1:cannot be resolved. Error 2:cannot be resolved to a variable. Error 3:undefined for the type AcceptSocket.
import java.io.IOException;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
public class AcceptSocket extends Thread {
private static final String MY_UUID = null;
BluetoothServerSocket mmServerSocket;
public void AcceptThread() {
// Use a temporary object that is later asssigned to mmServerSocket,
// because mmServerSocket is final
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = ||1|mBluetoothAdapter|||.listenUsingRfcommWithServiceRecord(||2|NAME|||,
MY_UUID);
} catch (IOException e) {
}
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
// Do work to manage the connection (in a separate thread)
||3|manageConnectedSocket|||(socket);
mmServerSocket.close();
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) {
}
}
}
Error 1,2: There is no constant called NAME anywhere in the class.
Error 3: There is no method called manageConnectedSocket() in the class.
You can't just copy and paste something from the developer's page and expect it to work. It leads you in the correct direction and you have to fill in the missing pieces.

Categories

Resources