Cannot send data outside runnable thread - java

I'm having some difficulties with my app. I created a class with functions to handle HTTP POST by starting a thread, the issue is that I cannot send data outside the thread!!! The class has a variable and I want to set value to that variable when the thread is running, please help.
Here is the code:
package com.mypackage;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import org.json.JSONObject;
import org.json.JSONException;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Handler;
import android.util.Log;
public class HandleJSON {
private String urlString = null;
private int errorcode ;
public int getErrorcode(){return errorcode;}
public volatile boolean parsingComplete = true;
public HandleJSON(String url){
//saving the URL
this.urlString = url;
}
#SuppressLint("NewApi")
public void readAndParseJSON(String in) {
try {
parsingComplete = false;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void fetchJSON(){
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
try {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.connect();
//receiving message from server
InputStream stream = conn.getInputStream();
String data = convertStreamToString(stream);
// JSON thing
try{
JSONObject obj = new JSONObject(data);
//THIS IS THE ISSUE, I'm setting here the errorcode which should set the superclass variable "errorcode" so I can use "getErrorCode" to retrieve the code, but it seems like the thread does not respond after thread starts;
errorcode = obj.getInt("error_code");
}
catch(JSONException e) {
Log.e("Catch error", e.toString());
}
readAndParseJSON(data);
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
}
static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
}

If I understand correctly, you want to get data between a non-main thread and elsewhere. In which case you may want to create another class that has a public static variable. This is such that everyone permitted by the modifier in question (private, protected, public) can access the same content. Be careful as, if poorly managed, your code may function differently or not all on systems with execution speeds other than yours.

In such case, an anonymous daemon thread is a little tricky.
You can define a concrete class extending Thread, define data structures in it and provide the interface to access your data structures. Such as here below.
class MyThread extends Thread {
private JSONObject obj;
public void run() {
// Your parsing code goes here
// Such as obj = xxxxxx;
}
public JSONObject getData() {
return obj;
}
}
Of course, you should consider the concurrent risks when manipulating inner data structures.

The issue solved, I used AsyncTask instead and passed the variables to onPostExecute(String) which done the trick.

Related

read JSON from url on JavaFX controller does not update when JSON updated

I try to create java program that read JSON from this url, the url contain JSON array that updated every 20 seconds here is my java program that listen to the url and print the last JSON object from the JSON file:
ListenTojson.java
package com.company;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.*;
import java.net.URL;
import java.nio.charset.Charset;
class ListenToJson implements Runnable {
public void run() {
long tenSeconds = 10*1000L;
while(true) {
try {
JSONArray json = readJsonFromUrl("http://frozen-brook-16337.herokuapp.com/history.json");
JSONObject jo=json.getJSONObject(json.length()-1);
System.out.println(jo.get("data"));
Thread.sleep(tenSeconds);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private static String readAll(Reader rd) throws IOException {
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
return sb.toString();
}
public static JSONArray readJsonFromUrl(String url) throws IOException, JSONException {
InputStream is = new URL(url).openStream();
try {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")));
String jsonText = readAll(rd);
JSONArray jsonArray = new JSONArray(jsonText);
return jsonArray;
} finally {
is.close();
}
}
}
Main.java
package com.company;
public class Main {
public static void main(String[] args){
(new Thread(new ListenToJson())).start();
}
}
The code run as I expected. The JSON file contains coordinate that keep updated every 10 seconds. I need to create map application that read the coordinate from the JSON and then show it on the map as marker, I use JavaFx library to create the map application, when I add the code above (ListenToJson.java) the program behave differently when I use JavaFX library it does not read the latest JSON file.
here is the code
public class Controller{
//some code
(new Thread(new ListenToJson())).start();
//some code
}
Controller.java
The full class that I try to update the UI using the ListenToJson() function is here https://github.com/kikirizki/mapapp/blob/master/src/main/java/com/delameta/vesselmap/Controller.java the line 526, thanks
whats wrong with my code, why the ListenToJson() function read the outdated JSON file ?
I found the solution myself, the problem is the mapjfx library (I use in the code) use cache to cache the map tile and then it cause to cache the JSON file too. The solution is simply disable the cache mechanism, just diable it at line 350, change
offlineCache.setActive(true);
to be
offlineCache.setActive(false);

How to give file as input and work in multiple threads?

I have this code to find out how to get the status code from a URL:
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
/**
* #author Crunchify.com
*
*/
class j {
public static void main(String args[]) throws Exception {
String[] hostList = { "http://example.com", "http://example2.com","http://example3.com" };
for (int i = 0; i < hostList.length; i++) {
String url = hostList[i];
String status = getStatus(url);
System.out.println(url + "\t\tStatus:" + status);
}
}
public static String getStatus(String url) throws IOException {
String result = "";
try {
URL siteURL = new URL(url);
HttpURLConnection connection = (HttpURLConnection) siteURL
.openConnection();
connection.setRequestMethod("HEAD");
connection.connect();
int code = connection.getResponseCode();
result = Integer.toString(code);
} catch (Exception e) {
result = "->Red<-";
}
return result;
}
}
I have checked it for small input it works fine. But I have millions of domains which I need to scan. I have a file containing it.
I want to know how I can give file as an input to this code.
I want the code to work in Multiple Threads. Say Thread count should be more than 20000, so that my output will be faster.
How I can write the out to another file?
Kindly help me. If possible I would like to know which the Bandwidth Savvy method to do the same job. I want to make the code faster anyways. how I can do these thing with the code I have?
Java Version:
java version "1.8.0_121"
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
This does what you want:
Input list file (c://lines.txt)
http://www.adam-bien.com/
http://stackoverflow.com/
http://www.dfgdfgdfgdfgdfgertwsgdfhdfhsru.de
http://www.google.de
The Thread:
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.Callable;
public class StatusThread implements Callable<String> {
String url;
public StatusThread(String url) {
this.url = url;
}
#Override
public String call() throws Exception {
String result = "";
try {
URL siteURL = new URL(url);
HttpURLConnection connection = (HttpURLConnection) siteURL.openConnection();
connection.setRequestMethod("HEAD");
connection.connect();
int code = connection.getResponseCode();
result = Integer.toString(code);
} catch (Exception e) {
result = "->Red<-";
}
return url + "|" + result;
}
}
And the main program:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Stream;
public class CallableExample {
public static void main(String[] args) throws IOException {
// Number of threads
int numberOfThreads = 10;
// Input file
String sourceFileName = "c://lines.txt"; // Replace by your own
String targetFileName = "c://output.txt"; // Replace by your own
// Read input file into List
ArrayList<String> urls = new ArrayList<>();
try (Stream<String> stream = Files.lines(Paths.get(sourceFileName ))) {
stream.forEach((string) -> {
urls.add(string);
});
} catch (IOException e) {
e.printStackTrace();
}
// Create thread pool
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(numberOfThreads);
List<Future<String>> resultList = new ArrayList<>();
// Launch threads
for(String url : urls) {
StatusThread statusGetter = new StatusThread(url);
Future<String> result = executor.submit(statusGetter);
resultList.add(result);
}
// Use results
FileWriter writer;
writer = new FileWriter(targetFileName);
for (Future<String> future : resultList) {
try {
String oneResult = future.get().split("\\|")[0] + " -> " + future.get().split("\\|")[1];
// Print the results to the console
System.out.println(oneResult);
// Write the result to a file
writer.write(oneResult + System.lineSeparator());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
writer.close();
// Shut down the executor service
executor.shutdown();
}
}
Don't forget to:
Create your input file and point to it (c://lines.txt)
Change the number of threads to get the best result
You will have issues sharing a file across threads. Much better to read the file and then spawn a thread to process each record in the file.
Creating a thread is none trivial resource wise so a thread pool would be useful so threads can be reused.
Do you want all threads to write to a single file?
I would do that using a shared list between the threads and the writer. others may have a better idea.
How to do all this depends on Java version.
You can use the ExecutorService and set the thread number to use.
The ExecutorService instance will handle for your the threads management.
You just need to provide it the tasks to execute and invoking all tasks executions.
When all the task are performed you can get the result.
In the call() method of The Callable implementation we return a String with a separator to indicate the url and the response code of the request.
For example : http://example3.com||301, http://example.com||200, etc...
I have not written the code to read a file and store in another file the result of the tasks. You should not have great difficulty to implement it.
Here is the main class :
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Main {
public static void main(String[] args) throws InterruptedException {
String[] hostList = { "http://example.com", "http://example2.com", "http://example3.com" };
int nbThreadToUse = Runtime.getRuntime().availableProcessors() - 1;
ExecutorService executorService = Executors.newFixedThreadPool(nbThreadToUse);
Set<Callable<String>> callables = new HashSet<Callable<String>>();
for (String host : hostList) {
callables.add(new UrlCall(host));
}
List<Future<String>> futures = executorService.invokeAll(callables);
for (Future<String> future : futures) {
try {
String result = future.get();
String[] keyValueToken = result.split("\\|\\|");
String url = keyValueToken[0];
String response = keyValueToken[1];
System.out.println("url=" + url + ", response=" + response);
} catch (ExecutionException e) {
e.printStackTrace();
}
}
executorService.shutdown();
}
}
Here is UrlCall, the Callable implementation to perform a call to the url.
UrlCall takes in its constructor the url to test.
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.Callable;
public class UrlCall implements Callable<String> {
private String url;
public UrlCall(String url) {
this.url = url;
}
#Override
public String call() throws Exception {
return getStatus(url);
}
private String getStatus(String url) throws IOException {
try {
URL siteURL = new URL(url);
HttpURLConnection connection = (HttpURLConnection) siteURL.openConnection();
connection.setRequestMethod("HEAD");
connection.connect();
int code = connection.getResponseCode();
return url + "||" + code;
} catch (Exception e) {
//FIXME to log of course
return url + "||exception";
}
}
}
I agree with Thread pool approach exposed here.
Multi-threading consists in exploiting the time the others threads spend to wait (I guess int his case: the distant site response). It does not multiply processing power. Then about 10 threads seem reasonable (more depending on hardware).
An important point that seem to have been neglected in answer I read is that OP talk about millions of domains. Then I would discourage loading whole file in memory in a list iterated over afterwards. I would rather merge all in a single loop (file reading), instead of 3 (read, ping, write).
stream.forEach((url) -> {
StatusThread statusGetter = new StatusThread(url, outputWriter);
Future<String> result = executor.submit(statusGetter);
});
outputWriter would be a type with a synchronized method to write into an output stream.

How to handle asynctask during phone call and apps in background android

i have made an app, which sending/receiving lat long to/from server continuously.also retrieving and showing information from server.i have used asynctask for network call. but one problem when phonecall came and apps in background my apps lost its connection;like not show any server information nor send lat long to server in right destination. how to solve this? like if i would use volley then singleton class may help to solve this problem is there any solution for asynctask?
this is my asynctask:
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class
GetPostAsyncTask extends AsyncTask<String, Void, String> {
public AsyncResult asyncResult;
// HttpURLConnection httpURLConnection;
// private static String responseStr = "";
// private static String responseStrLogin = "";
ProgressDialog progressDialog;
private final String baseUrl = UserInfo.getBaseUrl();
Context context;
GetPostAsyncTask(Context context,AsyncResult asyncResult) {
this.context=context;
this.asyncResult= asyncResult;
}
#Override
protected void onPreExecute() {
//Toast.makeText(context,"Loading..",Toast.LENGTH_SHORT).show();
progressDialog=new ProgressDialog(context);
progressDialog.show();
}
#Override
protected String doInBackground(String... args) {
try {
// setting the URL
URL url = new URL(baseUrl+args[1]);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.addRequestProperty("User-Agent", "RealTimeApps/1.0");
// setting the method type
httpURLConnection.setRequestMethod(args[0]);
// httpURLConnection.setChunkedStreamingMode(0);
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
OutputStream outputStream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
Log.v("Url",args[2]);
// setting the identification key name with query params
bufferedWriter.write(args[2]);
bufferedWriter.flush();
bufferedWriter.close();
Log.v("GetPostA", url.toString());
httpURLConnection.connect();
int getPostStatus = httpURLConnection.getResponseCode();
Log.v("GetPostSts", String.valueOf(getPostStatus));
String line = "";
String res = "";
// if(getPostStatus == 200){
// prepare the output buffer
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
while ((line = bufferedReader.readLine()) != null) {
res += line;
}
inputStream.close();
// }
httpURLConnection.disconnect();
return res.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
Log.v("GetPostCatchMal",e.toString());
} catch (IOException e) {
e.printStackTrace();
Log.v("GetPostCatchIOE", e.toString());
}
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
progressDialog.dismiss();
if(result!=null) {
asyncResult.asyncResult(result);
}
}
}
i am very new in android and unable to find the solution of this problem.any help please. TIA
You need to listen to incoming calls using an IncomingCallReceiver (user-defined : code given below) and suspend/stop your Asynctask when you receive a call, and resume/restart it when the call ends.
For stop-restart case:
In your Asynctask you can make it loop on a sharedpreference flag variable for continuous behavior and set the flag to false when call comes. When call ends, you can initiate the Asynctask again.
Code for IncomingCallReceiver:
public class IncomingCallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// 2
this.context = context;
try{
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (TelephonyManager.EXTRA_STATE_RINGING.equals(state))
{
//Call incoming
}
else if(TelephonyManager.EXTRA_STATE_OFFHOOK.equals(state))
{
//Call picked up
}
else if(TelephonyManager.EXTRA_STATE_IDLE.equals(state))
{
//Call ends
}
}
catch(Exception e)
{
e.printStackTrace();
}
Incoming call receiver tutorial: http://www.theappguruz.com/blog/detecting-incoming-phone-calls-in-android
Shared preferences tutorial : https://www.tutorialspoint.com/android/android_shared_preferences.htm
Asynctask tutorial: https://developer.android.com/reference/android/os/AsyncTask.html
Singleton class tutorial: https://sourcemaking.com/design_patterns/singleton
You can run that code in a Service. The service can run in the background (even when app is paused/stopped) - which means that even when a phone call comes in (which puts your activity in paused state) your code should run without interruptions.
Make sure you read more about the lifecycle of the Service to implement what you're trying to do properly.
EDIT:
To run the AsyncTask within the Service, create an instance of that task when creating the Service (see Service lifecycle) and run the task there.
When you try to start a Service that is already running, it won't create another instance but rather will return an instance of the running Service, however it will call onStartCommand again.
You can bind the service to your activity(s) to communicate with it.
1.
<service
android:name=".AsyncTaskInServiceService">
</service>
2.
public class ServiceReciever extends BroadcastReceiver {
#Override
public void onReceive(final Context context, Intent intent) {
TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(new PhoneStateListener(){
#Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
System.out.println("incomingNumber : " + incomingNumber);
Toast.makeText(context,incomingNumber,Toast.LENGTH_LONG).show();
Asynchtask().execute();//Write the code here
}
},PhoneStateListener.LISTEN_CALL_STATE);
}

Implements of thread in Android doesn't work

I'm writing a basic application in Android, the application will be connected to MySql server by quest in PHP, in Android Internet connection have to make in diffrent thread, so I create class which implements Runnable interface.
package com.company.opax.loginmysql;
import android.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
/**
* Created by opax on 30.08.2015.
*/
public class HttpPostMethod implements Runnable{
private String fileInHost;
private ArrayList<PostParameters> postParameterses;
private StringBuffer postResult;
public HttpPostMethod(String fileInHost, ArrayList<PostParameters> postParameterses){
this.fileInHost = fileInHost;
this.postParameterses = new ArrayList<PostParameters>(postParameterses);
}
public String getResult() {
return postResult.toString();
}
#Override
public void run() {
try {
String urlParameters = generateParameters();
URLConnection conn = initializeUrlConnection();
OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
writer.write(urlParameters);
writer.flush();
String line;
BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = reader.readLine()) != null) {
postResult.append(line);
}
writer.close();
reader.close();
} catch (IOException e) {
Log.e("Exception", this.getClass().getName() + " name: " + e.toString());
}
}
private URLConnection initializeUrlConnection() throws MalformedURLException {
URL url = new URL(fileInHost);
URLConnection conn;
try {
conn = url.openConnection();
conn.setDoOutput(true);
}catch(IOException e){
throw new MalformedURLException();
}
return conn;
}
private String generateParameters(){
StringBuffer finishPostQuery = new StringBuffer();
for(PostParameters p : postParameterses){
finishPostQuery.append(p.getNameParam());
finishPostQuery.append("=");
finishPostQuery.append(p.getValueParam());
finishPostQuery.append("&");
}
if(!finishPostQuery.toString().equals("login=seba&password=pass&"))
throw new AssertionError("blad generatora zapytania: " + finishPostQuery);
return finishPostQuery.toString();
}
}
and login class:
public class Login {
private User user;
private final String paramLogin = "login";
private final String paramPass = "password";
public Login(User user){
this.user = user;
}
public boolean tryLogin(){
try{
ArrayList<PostParameters> postParameterses = new ArrayList<>();
postParameterses.add(new PostParameters(paramLogin, user.getUserName()));
postParameterses.add(new PostParameters(paramPass, user.getUserPass()));
HttpPostMethod httpPostMethod = new HttpPostMethod("http://blaba.php", postParameterses);
httpPostMethod.run();
Log.i("bla", httpPostMethod.getResult());
} catch (Exception e) {
Log.i("Exception", e.toString());
}
return false;
}
}
I'm trying to connect in other thread, but I still have an error: 'android.os.NetworkOnMainThreadException'
I would be grateful for the all suggestion what I do wrong.
Instead of:
httpPostMethod.run();
do:
new Thread(httpPostMethod).start();
In case your login call failed for some reasons (timeout, wrong login), you should report that somehow to user - this is what AsyncTask class is for. It allows you to run background code in doInBackkground, and after network operation ends - in onPostExecute you can execute UI related stuff - like show errors/results.
I suggest you two things.
First use AsyncTask instead of pure java threads.
But the main advice is to use a library that make http requests.
I like to use Retrofit, it may handle all request and thread part for you, but there are others.

Use getJSONObject(int)

I'm trying to parse some JSON. Here is the code. frc-manual.usfirst.org/a/GetAllItems/ManualID=3 I have been trying for several hours to get it work but every example I have seen online uses getJSONObject(int) but I can only use getJSONObject(String). This is making impossible. Am I overlooking something?
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import android.annotation.SuppressLint;
public class JSON {
private String html = "html";
private String version = "version";
private String pageString = null;
private String urlString = "http://frc-manual.usfirst.org/a/GetAllItems/ManualID=3";
public volatile boolean parsingComplete = true;
public JSON(String page){
this.pageString = page;
}
public String getHTML(){
return html;
}
public String getVersion(){
return version;
}
#SuppressLint("NewApi")
public void readAndParseJSON(String in) {
try {
JSONObject reader = new JSONObject(in);
JSONObject head = reader.getJSONObject("data").getJSONObject("SubChapter").getJSONObject("3").getJSONObject("children").getJSONObject(pageString);
if(head != null){
html = head.getString("item_content_text");
html = html + head.length();
for(int i = 0; i < head.length();i++){
JSONObject children = head.getJSONObject(i);
if(children != null){
html = html + children.getString("item_content_text");
}
}
}
//html = html + listFromJsonSorted(head.getJSONObject("children"));
JSONObject main = reader.getJSONObject("data");
version = main.getString("LatestManualUpdate");
parsingComplete = false;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void fetchJSON(){
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
try {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
InputStream stream = conn.getInputStream();
String data = convertStreamToString(stream);
readAndParseJSON(data);
stream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
}
static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
}
Probably what you are seeing in this example is a JSONArray.
JSONArray arr = json.getJSONArray("array");
JSONObject obj = arr.getJSONObject(0);
In your case, i don't see any array in this JSON, head in your code is a JSONObject. To get the item_content_text you just need head.getString("item_content_text");
You can do this to get all childrens in your JSON:
html = head.getString("item_content_text");
JSONObject children = head;
while (children.containsKey("children")) {
children = children.getJSONObject("children");
html += children.getString("item_content_text");
}
You are only able to use getJSONObject(String) not getJSONObject(int) because the method only takes String.. Check documentation here..
The reason that is the because the keys in json are always strings only.. read here
I think you are looking to retrieve an int value from the json but you got confused.. The way to do that would be getInt("key_name") if the json indeed has a key with int value..
Sure you can, just that I think your "head" variable should have a return type of JSONArray instead of JSONObject.
I have this code running in my program -
//response = some http response
final JSONObject object = new JSONObject(response);
final JSONArray array = object.getJSONArray("repeatedStuff"); //$NON-NLS-1$
Assert.assertEquals(2, array.length());
for (int i = 0; i < array.length(); i++) {
final JSONObject element = array.getJSONObject(i);
//do something
}
Also you may refer this link to see what they are doing - android: The method getJSONObject(int) in the type JSONArray is not applicable for the arguments (String)
Let me know if that helped!
You have used JSONObject everywhere in your code. Thus you are only able to pass string parameter in getJSONObject().
I suggest you you change it to JSONArray and then you will be able to pass int parameter in getJSONObject().

Categories