Basically, i have an app that uses JSON. I get the JSON in new HentData.execute(); and pass it to a string variable. But when I try to acutally do something with it my program crashes.
HentData extends AsyncTask, I know it gives me a JSON string that works
INSIDE oncreate()
new HentData().execute();
jsonToArray();
arrayToText();
This crashes
But when I run them like this it works, do I have to close the HentData class somehow?
protected void onPostExecute(String resultat){
json_string = resultat;
jsonToArray();
arrayToText();
}
This is my doInBackground()
protected String doInBackground(Void... voids){
try {
URL url = new URL(json_url);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream IS = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(IS));
StringBuilder sb = new StringBuilder();
while((json_string = bufferedReader.readLine())!=null){
sb.append(json_string+"\n");
}
bufferedReader.close();
IS.close();
httpURLConnection.disconnect();
return sb.toString().trim();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
But when I run them like this it works, do I have to close the HentData class somehow?
protected void onPostExecute(String resultat){
json_string = resultat;
jsonToArray();
arrayToText();
}
You don't have to close anything. This works because "async" in AsyncTask makes the code run in the background.
In other words,
new HentData().execute(); // Not waiting for result
jsonToArray(); // Continue on, even though there is no result yet --> error
arrayToText();
If you want a more flexible way to get results, see How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?
If you hate writing AsyncTasks (for HTTP methods), see Comparison of Android networking libraries: OkHTTP, Retrofit, and Volley
Related
I'm writing a android trivia app that uses the Open Trivia DB to generate its questions. The problem I'm incurring is that I'm simply unable to connect to the generated API url and I'm not sure why.
I'm simply trying to pull the raw text from the URL and then sort it later, here is the relevant code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button start = (Button)findViewById(R.id.button);
try {
getJSON();
}
catch (IOException e){
Log.d("CREATION","Something wrong");
}
}
private String getJSON()throws IOException{
URL trivia = new URL("https://opentdb.com/api.php?amount=10");
URLConnection yc = trivia.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
yc.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
Log.d("CREATION",inputLine);
in.close();
return "";
}
}
The Stack trace from the errors I get comes back with this:
at edu.niu.students.z1802067.triviaapp.MainActivity.getJSON(MainActivity.java:59)
which is this line of code:
yc.getInputStream()));
How could I write this to simply get all the raw text from the JSON?
First of all you try make request with UI thread. It's blocking UI for a long time (time of request)
Try use thread like this:
new Thread(){
#Override
public void run() {
try {
getJSON();
}
catch (IOException e){
Log.d("CREATION","Something wrong: " + e, e);
}
}
}.start();
Better solution for reading data form API is use library like https://square.github.io/retrofit/
It simplifies the task and data processing
EDIT: AsyncTask was called lots of times to update status in Server
and at the same time, my app tried to upload files. AsyncTask by
default, do only one operation at a time (serial mode) but you can put
it in Parallel mode, as I answered below.
After running normally during several hours (and sometimes a few minutes), my app stops connecting to the server with HTTPost. I set the Timeout to 20 sec and It's a good time since the connection is good (wifi). I have tested it in two servers: my own computer and a virtual private server. The problem happens equally.
Is there some way or reason for Android to avoid connecting to the http server?
Is there another reason for this to happen?
Is there a better way of doing this?
Thanks!!
This is how I make a POST request:
try{
new ConexaoHTTPPost.SolicitaDados(parametros).execute(url).get(20000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
new ReportException(getApplicationContext()).send(e,classeToErr);
} catch (ExecutionException e) {
new ReportException(getApplicationContext()).send(e,classeToErr);
} catch (TimeoutException e) {
new ReportException(getApplicationContext()).send(e,classeToErr);
}
HTTPost Code:
public class ConexaoHTTPPost {
public static String postDados(String urlUsuario, String parametrosUsuario) {
URL url;
HttpURLConnection connection = null;
try {
url = new URL(urlUsuario);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Lenght","" + Integer.toString(parametrosUsuario.getBytes().length));
connection.setRequestProperty("Content-Language","pt-BR");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
outputStreamWriter.write(parametrosUsuario);
outputStreamWriter.flush();
outputStreamWriter.close();
InputStream inputStream = connection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
StringBuffer resposta = new StringBuffer();
String linha;
while ( (linha = bufferedReader.readLine()) != null){
resposta.append(linha);
resposta.append('\r');
}
bufferedReader.close();
return resposta.toString();
}catch (Exception erro){
return null;
}finally {
if(connection != null){
connection.disconnect();
}
}
}
public static class SolicitaDados extends AsyncTask<String, Void, String> {
private String parametros;
//private String resultado = null;
public SolicitaDados(String parametros) {
this.parametros = parametros;
}
#Override
protected String doInBackground(String... urls) {
return ConexaoHTTPPost.postDados(urls[0], parametros);
}
/*
#Override
protected void onPostExecute(String resultado){
this.resultado = resultado;
}
*/
}
}
I solved It.
I was using execute() method but, actually, the correct way is to use executeOnExecutor() in this line:
new ConexaoHTTPPost.SolicitaDados(parametros).execute(url).get(20000,
TimeUnit.MILLISECONDS);
execute() executes everything in serial in the UI Thread, so you can't upload two files (or data) at the same time because the connection get blocked by the UI thread.
When using executeOnExecutor() method, you can upload multiple files ou data. I had only to change this line as shown:
new ConexaoHTTPPost.SolicitaDados(parametros).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
url).get(20000, TimeUnit.MILLISECONDS);
I changed it in all places it appears.
PS: You have to use AsyncTask.THREAD_POOL_EXECUTOR as a Thread Executor.
I'm making a small dictionary kind of app using java swings. I'm using oxford dictionary api for that. Is there any way to make a simple ajax request in java without using servelets and all advanced java concepts. As in android we use http url connection to do this job.I googled a lot for finding this but I could't find a solution as every page is showing results using servelets. But I know core java alone.If it is possible to make ajax call without servelts please help me...Thanks in advance...
Use HttpURLConnection class to make http call.
If you need more help for that then go for offical documentation site of java Here
Example
public class JavaHttpUrlConnectionReader {
public static void main(String[] args) throws IOException{
String results = doHttpUrlConnectionAction("https://your.url.com/", "GET");
System.out.println(results);
}
public static String doHttpUrlConnectionAction(String desiredUrl, String requestType) throws IOException {
BufferedReader reader = null;
StringBuilder stringBuilder;
try {
HttpURLConnection connection = (HttpURLConnection) new URL(desiredUrl).openConnection();
connection.setRequestMethod(requestType);// Can be "GET","POST","DELETE",etc
connection.setReadTimeout(3 * 1000);
connection.connect();// Make call
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));// Reading Responce
stringBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
return stringBuilder.toString();
} catch (IOException e) {
throw new IOException("Problam in connection : ", e);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ioe) {
throw new IOException("Problam in closing reader : ", ioe);
}
}
}
}
}
It will make a call and give response as return string. If you want to make POST call the need to do some extra for that :
try{
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.write(postParam.getBytes());
} catch(IOException e){
}
Note : Here postParam is String type with value somthing like "someId=156422&someAnotherId=32651"
And put this porson befor connection.connect() statement.
I was being a bit naive, thinking I can read webpages the same way as you do in Java, but apparently you need to use threads or AsyncTask. Which I have no prior experience in and are proving to be hassle.
I've read http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html (3. point) which I semi understand but when I try to implement into my problem it all falls apart.
Here's my problem:
I need to read from an URL, it's a RSS feed.
Parse it all together
Insert it into ListView (arrayadapter)
This is my AsyncTask class, that I tried to recreate. I just want it to return a buffered reader, or the whole page but it's always null.
private class DownloadWebPageTask extends AsyncTask<String, Void, BufferedReader> {
#Override
protected BufferedReader doInBackground(String... urls) {
BufferedReader bs;
URL url = null;
try {
url = new URL(urls[0]);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
bs = new BufferedReader(new InputStreamReader(url.openStream(), "UTF-8"));
return bs;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(BufferedReader result) {
br = result;
}
}
public RSS() throws IOException, ExecutionException, InterruptedException {
DownloadWebPageTask dl = new DownloadWebPageTask();
dl.execute(new String[] {"http://www.promet.si/dc/PROMET.ROADEVENTS.PP.RSS.SL"});
}
I'm sorry if this is a stupid question, but I don't fully understand posts explaining this and I have to solve this problem. I just need the page's content in any way shape or form. (Can be a String, BufferedReader)
#Override
protected String doInBackground(String... urls) throws IOException {
URLConnection connection = new URL(urls[0]).openConnection();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()),"UTF-8");
StringBuilder stringBuilder = new StringBuilder();
String buffer;
while ((buffer = bufferedReader.readLine()) != null) {
stringBuilder.append(buffer);
}
return stringBuilder.toString();
}
Use the buffered reader to read line by line in the background thread, and make it return string.
I have an external .hash file which I tired reading as a simple remote text file:
private class getHash extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... params) {
String str = null;
try {
// Create a URL for the desired page
URL url = new URL(params[0]);
// Read all the text returned by the server
InputStream is = url.openStream();//The line it crashes on
InputStreamReader isr = new InputStreamReader(is);
BufferedReader in = new BufferedReader(isr);
str = in.readLine();
in.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
#Override
protected void onPostExecute(String result) {
hash = result;
}
}
Then I call the thread :
getHash hashThread = new getHash();
hashThread.execute(new String[]{"http://www......................hash"});
During execution of the noted line in the class all stops are pulled and I get slapped by the classy Source not found crash.
LogCat gives this error:
W/dalvikvm(724): threadid=1: thread exiting with uncaught exception (group=0x40a13300)
Are you running this in debug mode or regular mode?
The source not found message would seem to indicate you are trying to step into code that has no source attached for it.
Also have you added
<uses-permission android:name="android.permission.INTERNET" />
to your AndroidManifest.xml?