I am parsing json from url, the below code is simplified one which doesn't work. I am getting a NullPonterException at JSONObject json=jsonParser.getJSONFromUrl(GETSCHOOL_URL);.I found many people have searched for these particular problem, but I couldn't find any solution for my case.
public class SearchActivity extends Activity {
AutoCompleteTextView act;
JSONParser jsonParser;
private static final String TAG_SUCCESS = "success";
private static final String GETSCHOOL_URL = "http://sample.com/json";
private static final String TAG_STATUS = "status";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
Button b= (Button) findViewById(R.id.button);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new GetSchools().execute();
}
});
}
class GetSchools extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.d("request!", "starting");
}
#Override
protected String doInBackground(String... args) {
String success;
try {
Log.d("request!", "starting");
JSONObject json = jsonParser.getJSONFromUrl(
GETSCHOOL_URL);
Log.d("data", json.toString());
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
}
}
}
I think its silly mistake that I've done somewhere in program
You're never initializing jsonParser in the code you pasted. It needs to be initialized before your asyncTask is called.
Related
I need to update a textView with data from remote db MYSQL, but I have a problem when I try to update the textview in AsyncTask.I tryed everything but it always give me a void textview.
This is my code:
public class Credits extends Activity implements OnClickListener{
private Button home;
private String user;
public TextView totSpesa;
private ProgressDialog pDialog;
JSONParser jsonParser = new JSONParser();
private static final String URL = "http://**********/services.php";
private static final String TAG_SUCCESS = "success";
private static final String TAG_MESSAGE = "message";
private static final String TAG_ERROR_MESSAGE = "error_msg";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_credits);
user=PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString("id", "");
totSpesa= (TextView)findViewById(R.id.tot_spesa);
home = (Button)findViewById(R.id.home_btn);
home.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.home_btn:
Intent i = new Intent(Credits.this, MainActivity.class);
startActivity(i);
break;
default:
break;
}
}
class AttemptCredits extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
boolean failure = false;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Credits.this);
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String... args) {
// TODO Auto-generated method stub
//Intent in = getIntent();
//user = in.getStringExtra("id");
String tot_spesa="";
try {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("tag", "get_credits"));
params.add(new BasicNameValuePair("username", user));
Log.d("request!", "starting");
JSONObject json = jsonParser.makeHttpRequest(
URL, "POST", params);
tot_spesa=json.getString("tot_spesa");
} catch (JSONException e) {
e.printStackTrace();
}
return tot_spesa;
}
/**
* After completing background task Dismiss the progress dialog
* **/
#Override
protected void onPostExecute(String tot_spesa) {
totSpesa.setText(tot_spesa);
}
}
}
Maybe I'm missing something but I don't think you're actually launching your AsyncTask.
Try to do :
new AttemptCredits().execute(user);
In onCreate,
and get your user in doInBackground with
user = args[1];
I have created a custom AsyncTask class named ConnectionHttp. Which have to return a Json String, when called by a button in the main activity (test1.java). Everything is okay for the connection and I can get the string.
The point is that I want to display a ProgressDialog on the main activity while the background task is runing but it does not work. i don't see any ProgressDialog.
1) How can i fix the progressDialog
2) How can i solve the problem in logs (the application may be doing too much work ...) (I'm testing on a real device)
Here is my code :
test1.java (main activity)
public class test1 {
public static final String URL = ".....";
private ProgressDialog pDialog;
private TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test1);
pDialog = new ProgressDialog(test1.this);
tv = (TextView)findViewById(R.id.tvTest);
Button btRun = (Button) findViewById(R.id.btTestRun);
btRun.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
ConnectionHttp conn = new ConnectionHttp(test1.this, pDialog, URL);
String str = conn.execute().get();
tv.setText(str);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
});
}
ConnectionHttp.java
public class ConnectionHttp extends AsyncTask
{
private ProgressDialog pDialog;
private Context context;
private String LOGIN_URL;
private JSONParser jsonParser;
// TAGS
private final String TAG_SUCCESS = "success";
private final String TAG_MESSAGE = "message";
private final String TAG_VALUES = "values";
public ConnectionHttp(Context context, ProgressDialog pDialog, String url) {
this.context = context;
this.pDialog = pDialog;
this.LOGIN_URL = url;
this.jsonParser = new JSONParser();
}
#Override
public void onPreExecute() {
super.onPreExecute();
pDialog.setMessage("Connexion au serveur distant...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
public String doInBackground(String... args) {
// TODO Auto-generated method stub
int success;
String values = "";
try {
List<NameValuePair> params = new ArrayList<>();
// adding parameters
// ...
params.add(.....);
//
Log.d("request #1", "starting");
JSONObject json = jsonParser.makeHttpRequest(LOGIN_URL, "POST", params);
// success tag for json
success = json.getInt(TAG_SUCCESS);
if (success == 1) {
Log.d("request #1", "Successfull");
values = json.getString(TAG_VALUES);
return json.getString(TAG_MESSAGE);
}else{
return json.getString(TAG_MESSAGE);
}
} catch (JSONException e) {
e.printStackTrace();
}
return values;
}
public void onPostExecute(String message) {
Log.d("request #1", "done.");
pDialog.setMessage("done.");
pDialog.dismiss();
}
Android logs
D/request #1﹕ starting
D/request #1 : Successfull !
I/Choreographer﹕ Skipped 49 frames! The application may be doing too much work on its main thread.
D/request #1﹕ done
Dont pass progress dialog to the Async class. Instead create it on the Async class.
Modify onPreExecute to this
#Override
public void onPreExecute() {
super.onPreExecute();
pdialog = new ProgressDialog(getActivity(),"","Connexion au serveur distant...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
Delete progress dialog from test1.java
first remove your progress dialog from AsyncTask and use your passed context to create ProgressDialog;
public ConnectionHttp(Context context, ProgressDialog pDialog, String url) {
this.context = context;
this.pDialog = new ProgressDialog(context);
this.LOGIN_URL = url;
this.jsonParser = new JSONParser();
}
I have two asynctask in one class and i am having trouble in executing them at the same time.
Here is my scenario, my the user clicks the view january calendar button it will show up the events for the month of calendar and the comments for it. The events and comments are stored in mysql database so i have to fetch different url. I used asyctask to fetch the url. Whenever i call the other asynctask it cannot be resolved. help me out!
Here is my code:
package sscr.stag;
#SuppressLint("ShowToast")
public class Calendar extends ListActivity {
// All xml labels
TextView txtEvent;
// Progress Dialog
private ProgressDialog pDialog;
JSONArray user;
JSONObject hay;
private static final String CALENDAR_URL = "http://www.stagconnect.com/StagConnect/calendar/januaryCalendar.php";
private static final String COMMENT_URL = "http://www.stagconnect.com/StagConnect/calendar/januaryReadComment.php";
private static final String TAG_USER = "username";
private static final String TAG_MESSAGE = "message";
private static final String TAG_TIME = "time";
private static final String TAG_ARRAY = "posts";
private JSONArray mCalendar = null;
private ArrayList<HashMap<String, String>> mCommentList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.calendaradmin);
txtEvent = (TextView) findViewById(R.id.event);
new LoadCalendar().execute();
new LoadCommentCal().execute(); // error here, says cannot be resolved in this type
}
private class LoadCalendar extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Calendar.this);
pDialog.setMessage("Loading Calendar.. ");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
protected String doInBackground(String... args) {
String json = null;
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(CALENDAR_URL);
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
json = EntityUtils.toString(resEntity);
Log.i("Profile JSON: ", json.toString());
} catch (Exception e) {
e.printStackTrace();
}
return json;
}
#Override
protected void onPostExecute(String json) {
super.onPostExecute(json);
pDialog.dismiss();
try
{
hay = new JSONObject(json);
JSONArray user = hay.getJSONArray("posts");
JSONObject jb= user.getJSONObject(0);
String event = jb.getString("activities");
txtEvent.setText(event);
}catch(Exception e)
{
e.printStackTrace();
}
}
public void updateJSONdata() {
mCommentList = new ArrayList<HashMap<String, String>>();
JSONParser jParser = new JSONParser();
JSONObject json = jParser.getJSONFromUrl(COMMENT_URL);
try {
mCalendar = json.getJSONArray(TAG_ARRAY);
for (int i = 0; i < mCalendar.length(); i++) {
JSONObject c = mCalendar.getJSONObject(i);
String username = c.getString(TAG_USER);
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_USER, username);
mCommentList.add(0, map);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
private void updateList() {
ListAdapter adapter = new SimpleAdapter(Calendar.this, mCommentList,
R.layout.calendar_comment, new String[] { TAG_MESSAGE,
TAG_USER, TAG_TIME }, new int[] { R.id.message,
R.id.username, R.id.time });
setListAdapter(adapter);
ListView lv = getListView();
lv.scrollTo(0, 0);
}
public class LoadCommentCal extends AsyncTask<Void, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(Calendar.this);
pDialog.setMessage("Loading Comments...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(Void... args) {
updateJSONdata();
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
pDialog.dismiss();
updateList();
}
}
}
}
Your second asynctask public class LoadCommentCal extends AsyncTask is inside the first asynctask!
You need to move it out of the first asynctask.
private class LoadCalendar extends AsyncTask<String, String, String> {
...
}
... other functions
private class LoadCommentCal extends AsyncTask<Void, Void, String> {
...
}
You are declaring lots of things inside the first AsyncTask I strongly reccomend to close your AsyncTask after the onPostExecute
#Override
protected void onPostExecute(String json) {
super.onPostExecute(json);
pDialog.dismiss();
try
{
hay = new JSONObject(json);
JSONArray user = hay.getJSONArray("posts");
JSONObject jb= user.getJSONObject(0);
String event = jb.getString("activities");
txtEvent.setText(event);
}catch(Exception e)
{
e.printStackTrace();
}
}
}
and then removing one } at the end of the java file (and also reindent if you wish)
I currently have multiple activity that needs to perform an asynctask for http post and I wish to make the asynctask as another class file so that the different activity can call the asynctask to perform the http post request and onPostExecute, call the method httpResult(result) in the activity that called the asynctask. I have tried to pass the activity in but I am unable to call the method in onPostExecute. How can I do that?
public class MyActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_MyActivity);
//logic here...
AsyncHttpPost asyncHttpPost = new AsyncHttpPost("someContent", this, dialog);
JSONObject data = new JSONObject();
data.put("key", "value");
try {
asyncHttpPost.execute(data);
}
catch (Exception ex){
ex.printStackTrace();
}
}
public static void httpResult(String result) {
//this method has to get called by asynctask to make changes to the UI
}
}
AsyncHttpPost.java
public class AsyncHttpPost extends AsyncTask<JSONObject, String, String> {
String recvdjson;
String mData="";
private ProgressDialog dialog;
private Activity activity;
public AsyncHttpPost(String data, Activity activity, ProgressDialog dialog) {
mData = data;
this.activity = activity;
this.dialog = dialog;
}
protected void onPreExecute()
{
dialog.show();
}
#Override
protected String doInBackground(JSONObject... params) {
//logic to do http request
return "someStringResult";
}
protected void onPostExecute(String result) {
dialog.dismiss();
activity.httpResult(result); //This line gives me error : The method httpResult(String) is undefined for the type Activity
}
}
Create an Interface called HttpResponseImpl in a seperate file and add the required method httpResult
interface HttpResponseImpl{
public void httpResult(String result);
}
Now implement this interface by you Activity class
public class MyActivity extends Activity implements HttpResponseImpl{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_MyActivity);
//logic here...
AsyncHttpPost asyncHttpPost = new AsyncHttpPost("someContent", this, dialog);
JSONObject data = new JSONObject();
data.put("key", "value");
try {
asyncHttpPost.execute(data);
}
catch (Exception ex){
ex.printStackTrace();
}
}
public void httpResult(String result){
//this method has to get called by asynctask to make changes to the UI
}
}
And your AsyncHttpPost class would be.
public class AsyncHttpPost extends AsyncTask<JSONObject, String, String> {
String recvdjson;
String mData="";
private ProgressDialog dialog;
private HttpResponseImpl httpResponseImpl;
public AsyncHttpPost(String data, HttpResponseImpl httpResponseImpl, ProgressDialog dialog) {
mData = data;
this.httpResponseImpl = httpResponseImpl;
this.dialog = dialog;
}
protected void onPreExecute()
{
dialog.show();
}
#Override
protected String doInBackground(JSONObject... params) {
//logic to do http request
return "someStringResult";
}
protected void onPostExecute(String result) {
dialog.dismiss();
httpResponseImpl.httpResult(result);
}
}
Implements this HttpResponseImpl interface with all you Activity class from which you want to do HttpRequest.
Generic AsyncTask Example
Call it like
new RetrieveFeedTask(new OnTaskFinished()
{
#Override
public void onFeedRetrieved(String feeds)
{
//do whatever you want to do with the feeds
}
}).execute("http://enterurlhere.com");
RetrieveFeedTask.class
class RetrieveFeedTask extends AsyncTask<String, Void, String>
{
String HTML_response= "";
OnTaskFinished onOurTaskFinished;
public RetrieveFeedTask(OnTaskFinished onTaskFinished)
{
onOurTaskFinished = onTaskFinished;
}
#Override
protected void onPreExecute()
{
super.onPreExecute();
}
#Override
protected String doInBackground(String... urls)
{
try
{
URL url = new URL(urls[0]); // enter your url here which to download
URLConnection conn = url.openConnection();
// open the stream and put it into BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
while ((inputLine = br.readLine()) != null)
{
// System.out.println(inputLine);
HTML_response += inputLine;
}
br.close();
System.out.println("Done");
}
catch (MalformedURLException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
return HTML_response;
}
#Override
protected void onPostExecute(String feed)
{
onOurTaskFinished.onFeedRetrieved(feed);
}
}
OnTaskFinished.java
public interface OnTaskFinished
{
public void onFeedRetrieved(String feeds);
}
I created a class DataAdapter which launches threads to get data from webservices. When called in an activity using
DataAdapter.InitData();
how can I know when both threads are finished?
Thanks
Jul
public class DataAdapter {
private final static String URL = "http://www.mywebservice.com";
private final static String URL_AD = "http://www.mywebservice2.com";
public void InitData(){
new GetInitData().execute(URL);
new GetAd().execute(URL_AD);
}
private static class GetInitData extends AsyncTask<String, Integer, JSONObject> {
protected JSONObject doInBackground(String... urls) {
JSONObject json = RestJsonClient.getJSONObject(urls[0]);
return json;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(JSONObject json) {
//process data
}
}
private static class GetAd extends AsyncTask<String, Integer, JSONObject> {
protected JSONObject doInBackground(String... urls) {
JSONObject json = RestJsonClient.getJSONObject(urls[0]);
return json;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(JSONObject json) {
//process data
}
}
}
Use this:
public class DataAdapter {
private final String URL = "http://www.mywebservice.com";
private final String URL_AD = "http://www.mywebservice2.com";
private boolean finished = false;
public void InitData(){
new GetInitData(this).execute(URL);
new GetAd(this).execute(URL_AD);
}
public void finished(){
if(!finished){
finished = true;
}else{
Log.d("TAG","Both have finished"):
}
private class GetInitData extends AsyncTask<String, Integer, JSONObject> {
Activity ac = null;
public GetInitData(Activity ac){
this.ac=ac;
}
protected JSONObject doInBackground(String... urls) {
JSONObject json = RestJsonClient.getJSONObject(urls[0]);
return json;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(JSONObject json) {
//process data
ac.finished();
}
}
private class GetAd extends AsyncTask<String, Integer, JSONObject> {
Activity ac = null;
public GetInitData(Activity ac){
this.ac=ac;
}
protected JSONObject doInBackground(String... urls) {
JSONObject json = RestJsonClient.getJSONObject(urls[0]);
return json;
}
protected void onProgressUpdate(Integer... progress) {
}
protected void onPostExecute(JSONObject json) {
//process data
ac.finished();
}
}
}
Add a synchronized method to you DataAdapter class which each of the AsyncTask calles in its onPostExecute(). Within this method you set a boolean variable indicating that the first job finished, when the second AsyncTask calls the method it checks whether the first thread has already finished. If both have finished you can go one with your custom code.