I have an application with 3 or more AsycTask that are called sequentially. Because these asyntasks are all similar, I created a separated class and it works properly.
Now I would like to add a progress bar in order to show something when these asynctasks ask and process the result...but not work.
My application work as follow:
I open my camera and with ZXing library I decode a qrCode
using HttpRequest I ask to my server some informations and my application processes these informations
The point is that during the processing my application shows a black screen with the tipical viewfinder of ZXing library (I think that you understand what I mean). How can replace this view with another block with a progress bar?
I already tried to modified the progress bar visibility, on the event onPreExecute and onPostExecute, also I tried to use the event onProgressUpdate, but nothig is change. The viewfinder remains on the screen until the asyncTask is not finish.
Follow my code for execute the AsyncTask:
response = asynkTaskDeleteMissionQueue.execute().get();
and my AsyncTask class
package com.klainrobotics.lucalombardi.krmir;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.ProgressBar;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.util.List;
import java.util.Vector;
/**
* Created by Luca Lombardi on 27/11/2017.
*/
public class MiRCall extends AsyncTask <String, Void, List<Object> >{
public AsyncResponse delegate = null;
private String url;
private String method;
private ProgressBar progress;
public MiRCall(Context v, ProgressBar prg, String...params){
method = params[0];
url = params[1];
progress = prg;
}
#Override
protected void onPreExecute(){
}
#Override
protected void onProgressUpdate(Void... v) {
super.onProgressUpdate(v);
}
#Override
protected List<Object> doInBackground(String... arg0) {
int result = -1;
publishProgress();
List<Object> response = new Vector<Object>();
String jsonResponse = "";
BufferedReader br;
try {
URL urlMissionQueue = new URL(url);
HttpURLConnection connection = (HttpURLConnection) urlMissionQueue.openConnection();
if (connection != null) {
connection.setRequestMethod(method);
connection.setRequestProperty(Costanti.headers, Costanti.StringaHeader());
connection.setRequestProperty(Costanti.contentType, Costanti.contentTypeJSon);
customBody(connection);
connection.connect();
result = connection.getResponseCode();
response.add(result);
if (200 <= result && result <= 299) {
br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
} else {
br = new BufferedReader(new InputStreamReader(connection.getErrorStream()));
}
for (String line; (line = br.readLine()) != null; jsonResponse += line);
response.add(jsonResponse);
}else {
Log.e("Url", "Connection is null");
}
} catch (Exception ex) {
Log.e("MiRCall", "doInBackgound: " + ex.toString());
}
return response;
}
#Override
protected void onPostExecute(List<Object> result) {
if (delegate != null) {
delegate.processFinish(result);
} else {
Log.e("MiRCall", "You have not assigned AsyncTask delegate");
}
}
public void customBody(HttpURLConnection connection) throws ProtocolException {
// Do nothing
}
}
Thanks in advance
response = asynkTaskDeleteMissionQueue.execute().get();
Pretty bad to use the .get() function on it. Do away with get(). Only start the task.
asynkTaskDeleteMissionQueue.execute();
Then in onPostExecute() handle the response.
Thanks for your suggestion. I execute
response = asynkTaskDeleteMissionQueue.execute().get();
because my asyncTask returns a list of object, so I don't know another way....
And about the original question? Any suggestions?
Thanks in any case for your time
Related
I'am following this tutorial for calling a web service in android & it works great, http://androidexample.com/Restful_Webservice_Call_And_Get_And_Parse_JSON_Data-_Android_Example/index.php?view=article_discription&aid=101
yet when i try to call another webservice using this code, just replacing the serverURL, the app gets blocked in th pre-execute(), can anyone tell me what else should I change ? I thought there was a common code for all web services ?
mainActivity.java
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import org.apache.http.client.HttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button GetData = (Button) findViewById(R.id.GetServerData);
GetData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// WebServer Request URL
String serverURL = "http://androidexample.com/media/webservice/JsonReturn.php";
// String serverURL = "http://hmkcode.appspot.com/rest/controller/get.json";
// String serverURL="http://gdata.youtube.com/feeds/api/videos?q=Android&v=2&max-results=20&alt=jsonc&hl=en";
// Use AsyncTask execute Method To Prevent ANR Problem
new LongOperation().execute(serverURL);
}
}
);
}
class LongOperation extends AsyncTask<String, Void, Void> {
private final HttpClient Client = new DefaultHttpClient();
private String Content;
private String Error = null;
private ProgressDialog Dialog = new ProgressDialog(MainActivity.this);
String data = "";
TextView uiUpdate = (TextView) findViewById(R.id.output);
TextView jsonParsed = (TextView) findViewById(R.id.jsonParsed);
protected void onPreExecute() {
// NOTE: You can call UI Element here.
//Start Progress Dialog (Message)
Dialog.setMessage("Please wait..");
Dialog.show();
}
// Call after onPreExecute method
protected Void doInBackground(String... urls) {
/************ Make Post Call To Web Server *********/
BufferedReader reader=null;
// Send data
try
{
// Defined URL where to send data
URL url = new URL(urls[0]);
// Send POST data request
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write( data );
wr.flush();
// Get the server response
reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
// Read Server Response
while((line = reader.readLine()) != null)
{
// Append server response in string
sb.append(line + " ");
}
// Append Server Response To Content String
Content = sb.toString();
}
catch(Exception ex)
{
Error = ex.getMessage();
}
finally
{
try
{
reader.close();
}
catch(Exception ex) {}
}
/*****************************************************/
return null;
}
protected void onPostExecute(Void unused) {
// NOTE: You can call UI Element here.
// Close progress dialog
Dialog.dismiss();
if (Error != null) {
uiUpdate.setText("Output : " + Error);
} else {
// Show Response Json On Screen (activity)
uiUpdate.setText(Content);
//String OutputData = MainActivity.parse(Content);
//Show Parsed Output on screen (activity)
//jsonParsed.setText(OutputData);
}
}
}
}
I changed send PostRequest with this code: //SEND Get data reques HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setRequestMethod("GET");& it works
I'm making an android application that downloads some text from a web page and puts it in a String, then it prints the string in a TextView. But the content of the web page can change every seconds, so i want TextView to update in real-time, showing the new String every seconds. To download text from the webpage and set TextView's text I used AsyncTask, and i called the execute() in onCreate() method, in main Activity. I don't know how update it, without make application crashed.
Sorry for bad English, that's my MainActivity:
package com.example.pack;
import java.net.MalformedURLException;
import java.net.URL;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity
{
TextView textView;
URL url;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
url = null;
try
{
url = new URL("myURL");
}
catch (MalformedURLException e) {}
new VariabileLikeTask(textView).execute(url);
}
}
And that's my aSyncTask:
package com.example.pack;
import android.os.AsyncTask;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
public class VariabileLikeTask extends AsyncTask<URL, Void, CharSequence>
{
TextView textView;
public VariabileLikeTask(TextView textView)
{
this.textView = textView;
}
#Override
protected String doInBackground(URL... urls)
{
URL url = urls[0];
InputStream in = null;
int risposta = -1;
String text = "";
try
{
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection))
throw new IOException("No connection");
HttpURLConnection httpConn = (HttpURLConnection) conn;
httpConn.setAllowUserInteraction(false);
httpConn.setInstanceFollowRedirects(true);
httpConn.setRequestMethod("GET");
httpConn.connect();
risposta = httpConn.getResponseCode();
if (risposta == HttpURLConnection.HTTP_OK)
in = httpConn.getInputStream();
BufferedReader bf = new BufferedReader(new InputStreamReader(in));
text = bf.readLine();
in.close();
bf.close();
}
catch (Exception ex) {}
return text;
}
#Override
protected void onPostExecute(CharSequence text)
{
textView.setText(text);
}
}
Sorry if the format code is wrong, this is my first thread.
Isn't it a bad idea to run the AsyncTask frequently? This will make the app heavier in network operations.
If you mean the word real-time push notification or socket connection would be the best match. If you can't use a push notification because you are trying to fetch data from a Web page consider using a service class. Then simply make a timer task and run the AsyncTask after a small interval of time.
Here a simple demo of running the task after an interval of time,
private int m_interval = 5000; // 5 seconds by default, can be changed later
private Handle m_handler;
#Override
protected void onCreate(Bundle bundle)
{
...
m_handler = new Handler();
}
Runnable m_statusChecker = new Runnable()
{
#Override
public void run() {
//this function can change value of m_interval.
new VariabileLikeTask(textView).execute(url);
m_handler.postDelayed(m_statusChecker, m_interval);
}
}
void startRepeatingTask()
{
m_statusChecker.run();
}
void stopRepeatingTask()
{
m_handler.removeCallback(m_statusChecker);
}
In this post the user try to show dialog from AsyncTask, but the code it's the same to change txtBox in runtime, watch it!
Tell me if I helped you and good programming!
hi i am new learner of android and java.below this is my code. I having trouble to know where is the problem.
when i debug few times, it automatically enter debug mode after that. to fix that i have to restart the phone again. I check with other apps, it work just fine. just for the apps that i currently working on.
problem :
1. if i didn't enter data into the "dateTo" the program will stopped.
2. enter debug mode itself.
3. when i get the data from the array atList, then i key in another 'dateTo" to retrieve another data, but it doesn't replace the current data value. tq
package com.example.m2mai;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import org.json.JSONArray;
import org.json.JSONObject;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class RetrieveActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_retrieve);
}
public ArrayList<String> atList=new ArrayList<String>();
public ArrayList<String> dataList=new ArrayList<String>();
public void getStream(View v)
{
new MyAsyncTask().execute();
}
private class MyAsyncTask extends AsyncTask<String, Void, String>
{
protected String doInBackground(String... params)
{
return getData();
}
public long getDateTo()
{
EditText toText = (EditText)findViewById(R.id.dateTo);
String To = toText.getText().toString();
DateFormat dateFormatTo = new SimpleDateFormat("dd/MM/yyyy");
Date dateTo = null;
try {
dateTo = dateFormatTo.parse(To);
} catch (java.text.ParseException e) {
e.printStackTrace();
}
long timeTo = dateTo.getTime();
new Timestamp(timeTo);
return timeTo/1000;
}
protected String getData()
{
String toTS = ""+getDateTo();
String decodedString="";
String returnMsg="";
String request = "http://api.carriots.com/devices/{API_KEY}/streams/?order=-1&max=2&at_to="+toTS;
URL url;
HttpURLConnection connection = null;
try {
url = new URL(request);
connection = (HttpURLConnection) url.openConnection();
//establish the parameters for the http post request
connection.addRequestProperty("carriots.apikey", "somekey");
connection.addRequestProperty("Content-Type", "application/json");
connection.setRequestMethod("GET");
//create a buffered reader to interpret the incoming message from the carriots system
BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
while ((decodedString = in.readLine()) != null)
{
returnMsg+=decodedString;
}
in.close();
connection.disconnect();
JSONObject nodeRoot = new JSONObject(returnMsg);
JSONArray res = nodeRoot.getJSONArray("result");
for (int i = 0; i < res.length(); i++)
{
JSONObject childJSON = res.getJSONObject(i);
if (childJSON.get("data")!=null)
{
String value = childJSON.getString("data");
dataList.add(value);
JSONObject node=new JSONObject(value);
atList.add(node.get("temperature").toString());
}
}
}
catch (Exception e)
{
e.printStackTrace();
returnMsg=""+e;
}
//Log.d("returnMsg",returnMsg.toString());
return returnMsg;
}
protected void onPostExecute(String result)
{
//show the message returned from Carriots to the user
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
EditText myData1=(EditText)findViewById(R.id.editText1);
myData1.setText(atList.get(0));
EditText myData=(EditText)findViewById(R.id.editText2);
myData.setText(atList.get(1));
}
}
}
This line long timeTo = dateTo.getTime(); will throw a NullPointerException when the dateFormatTo.parse method throws a ParseException. This is going to happen when you come into the method with the To string not matching the specified format.
You're not exiting out of the flow so the long...getTime(); line runs, but dateTo is null resulting in a crash.
In the onPostExecute; you aren't verifying that atList has multiple elements. A JSON parse failure will leave atList empty and cause an index bounds exception for those 2 get calls.
These may not be the solutions to what you're seeing; but they will crash the app when these are hit in very likely situations; including the one you describe of an empty string for To.
As the comments mention; the logs will help see what's actually happening; but this is too big for a comment and those points are going to cause problems.
I'm new to android and I hope someone could help me here. I have an activity Faculty and a button.
This is my XML layout browse_faculty:
<Button
android:onClick="searchFSTEHandler"
android:id="#+id/bFSTE"
android:layout_width="220dp"
android:layout_height="80dp"
android:layout_alignLeft="#+id/bFBE"
android:layout_below="#+id/bFBE"
android:layout_marginTop="20dp"
android:text="#string/fste" />
and this is my Faculty Activity which displays the buttons:
I use Intent to view ListView
public class Faculty extends Activity{
#Override
protected void onCreate(Bundle BrowseFaculty) {
// TODO Auto-generated method stub
super.onCreate(BrowseFaculty);
setContentView(R.layout.browse_faculty);
}
//on the XML,this is the "searchFSTEHandler" i want to use to show ListView
public void searchFSTEHandler(View target){
Intent courseList = new Intent(this, HttpActivity.class);
startActivity(courseList);
}
}
and below is the "HttpActivity" class is the class that displays my ListView. This class read a php file which gets data from a MySQL server and converts to JSON data then parses it into a array list.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.ListActivity;
import android.widget.ArrayAdapter;
public class HttpActivity extends ListActivity {
public String f1 = "FSTE";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.faculty_course);
new getHttp().execute();
getHttp test =new getHttp();
String strJsonData = test.doInBackground(f1);
// Convert String JSON data to Java class
ArrayList<Courses> arrayCourse= test.parseJsonData(strJsonData);
//Create an ArrayAdapter which shows the ArrayList data
this.setListAdapter(new ArrayAdapter<Courses>(this,android.R.layout.simple_list_item_1,arrayCourse));
}
private class getHttp extends AsyncTask<String, Void, String> {
public getHttp() {
}
#Override
protected String doInBackground(String... faculty) {
InputStream is = null;
try {
URL url = new URL("http://10.0.2.2/sqlWebService.php?faculty=FSTE");
URLConnection con = url.openConnection();
con.setConnectTimeout(10000);
con.setReadTimeout(10000);
is = con.getInputStream();
BufferedReader br = new BufferedReader(
new InputStreamReader(is));
StringBuffer sb = new StringBuffer();
String str;
while ((str = br.readLine()) != null) {
sb.append(str);
}
return sb.toString();
} catch (IOException e) {
e.printStackTrace();
return "";
} finally {
try {
if (is != null)
is.close();
} catch (IOException e2) {
e2.printStackTrace();
}
}
}
//------------------------------------------------------
private ArrayList<Courses> parseJsonData(String strJson) {
ArrayList<Courses> Course = new ArrayList<Courses>();
try {
// Generate JSONArray object by JSON String data
JSONArray arr = new JSONArray(strJson);
//from the JSONArray, get one element (row) of JSONData
for (int i = 0; i < arr.length(); i++) {
//Get JSON Object which is one element of the array
JSONObject ob = arr.getJSONObject(i);
Courses exam = new Courses();
//get the value by key, and set to exam class
exam.setCode(ob.optString("code"));
//save exam class to exam array list
Course.add(exam);
}
} catch (JSONException e) {
e.printStackTrace();
}
return Course;
}
}
}
The application crashes as soon as I click on the button and gives a error:
"android.os.NetworkOnMainThreadException"
Help Please !
The problem that you are having is network operation like what you are trying to do cannot and should not be performed on the main UI thread. Doing so will lead to an ANR (Android Not Responding), which is exactly the kind of error you are getting just now. What you want to do is move your code to a separate thread or to an AsyncTask that will perform this action in the background on a different thread using the doInBackground() method which does not have access to your views on the main UI thread. For example,
private class ExampleOperation extends AsyncTask<String, Void, String> {
public ExampleOperation() { //ctor }
#Override
protected void onPreExecute() {
//things that you want to initialize and maybe show dialog to user.
}
#Override
protected String doInBackground(String... params) {
//this is where you perform that network related operation.
}
#Override
protected void onPostExecute(String result) {
//this is where get the results from the network related task.
}
#Override
protected void onProgressUpdate(Void... values) {
//you can update your progressbar if any; otherwise omit method.
}
}
Then all you have to do is call the AsyncTask where ever you want to use it: new ExampleOperation().execute();
You can't make HTTP calls in the main thread, they take too long and would make the UI unresponsive. You need to do it in an AsyncTask.
This is probably not very elegant, but what I'm trying to do is connect to a web service, fetch the JSON, parse it, create an object out of it, add that object to an ArrayList and then use that ArrayList to populate my ListView.
I'm trying to do all of this with AsyncTask.
SUMMARY: doInBackgroud takes a String of a url, uses it to connect to a web service. I get the JSON data as a string, parse it, construct a new object out of the data, and add it to ArrayList. Then in onPostExecute I'm trying to set the listadapter using an ArrayAdapter that utilizes my ArrayList.
Here's what I have:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import org.json.JSONArray;
import org.json.JSONObject;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.basic.DefaultOAuthConsumer;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.ArrayAdapter;
public class AllOffersListActivity extends ListActivity {
private static final String CONSUMER_KEY = "bla";
private static final String CONSUMER_SECRET = "bla";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new CreateArrayListTask().execute("http://example.com/sample.json");
}
private class CreateArrayListTask extends AsyncTask<String, Void, ArrayList<Offer>> {
private final ProgressDialog dialog = new ProgressDialog(AllOffersListActivity.this);
#Override
protected void onPreExecute() {
this.dialog.setMessage("Fetching offers...");
this.dialog.show();
}
#Override
protected ArrayList<Offer> doInBackGround(String...urls) {
ArrayList<Offer> offerList = new ArrayList<Offer>();
for(String url: urls) {
OAuthConsumer consumer = new DefaultOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
consumer.setTokenWithSecret("", "");
try {
URL url1 = new URL(url);
HttpURLConnection request = (HttpURLConnection) url1.openConnection();
// sign the request
consumer.sign(request);
// send the request
request.connect();
String JSONString = convertStreamToString(request.getInputStream());
JSONObject jObject = new JSONObject(JSONString);
JSONObject offerObject = jObject.getJSONObject("offer");
String titleValue = offerObject.getString("title");
//System.out.println(titleValue);
String descriptionValue = offerObject.getString("description");
//System.out.println(attributeValue);
JSONObject businessObject = offerObject.getJSONObject("business");
String nameValue = businessObject.getString("name");
Offer myOffer = new Offer(titleValue, descriptionValue, nameValue);
offerList.add(myOffer);
} catch (Exception e) {
e.printStackTrace();
}
}
return offerList;
}
#Override
protected void onPostExecute(ArrayList<Offer> offerList) {
if(this.dialog.isShowing())
this.dialog.dismiss();
setListAdapter(new ArrayAdapter<Offer>(AllOffersListActivity.this, android.R.layout.simple_list_item_1, offerList));
}
}
private String convertStreamToString(InputStream inputStream) throws IOException {
if(inputStream != null) {
Writer writer = new StringWriter();
char[] buffer = new char[1024];
try {
Reader reader = new BufferedReader( new InputStreamReader(inputStream, "UTF-8"));
int n;
while((n = reader.read(buffer)) != -1) {
writer.write(buffer, 0, n);
}
} finally {
inputStream.close();
}
return writer.toString();
} else {
return "";
}
}
}
I'm seeing two errors. One is on my private Async class: "The type AllOffersListActivity.CreateArrayListTask must implement the inherited abstract method AsyncTask<String,Void,ArrayList<Offer>>.doInBackground(String...)"
Secondly, on my doInBackGround Override, I'm getting: The method doInBackGround(String...) of type AllOffersListActivity.CreateArrayListTask must override or implement a supertype method
What am I missing here?
It's just a small typo; should be doInBackground instead of doInBackGround.
#LuxuryMode you have done mistake on doInBackGround
the correct spelling is doInBackground
asynctask must have to implement doInBackground method so it is not recognize this method because of wrong Name of method so it gives you error
The method doInBackGround(String...) of type AllOffersListActivity.CreateArrayListTask must
override or implement a supertype method