How to hard-code the url for JSON Parsing? - java

I would like to hard-code the url for JSON Parsing. Below here is my code:
I changed SERVER_API_URL to TEST_API_URL but it's not working.So, How to i put the hard-code url.
My JSON Parsing coding is different from other online JSON Parsing. Please help me take a look. Thanks.
private class LoadViewTask extends AsyncTask<Void, Integer, Void> {
//Before running code in the separate thread
#Override
protected void onPreExecute() {
//Create a new progress dialog
progressDialog = ProgressDialog.show(getActivity(), "Loading...",
"Loading exam timetable, please wait...", false, false);
}
//The code to be executed in a background thread.
#Override
protected Void doInBackground(Void... params) {
Context ctx = getActivity();
SharedPreferences prefs = ctx.getSharedPreferences(Constants.PREF_NAME, 0);
try {
// res1 = HttpClient.getData(ctx, Constants.SERVER_API_URL + "/timetable/semester/" + prefs.getString("Username", ""));
res1 = HttpClient.getCode(ctx, Constants.TEST_API_URL + "/timetable/semester/" + prefs.getString("Username", "")); //Testing using with my own Url but not working
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//after executing the code in the thread
#Override
protected void onPostExecute(Void result) {
//close the progress dialog
progressDialog.dismiss();
//initialize the View
if ((res1 != null) && (res1.getHttpCode() == 200)) {
ViewPager pager = (ViewPager) timetable.findViewById(R.id.pager_day);
String res = res1.getBody();
week = new Gson().fromJson(res, WeeklyTimetable.class);
if ((week.getMondayActivities().size() == 0) && (week.getTuesdayActivities().size() == 0) &&
(week.getWednesdayActivities().size() == 0) && (week.getFridayActivities().size() == 0) &&
(week.getThursdayActivities().size() == 0) && (week.getSaturdayActivities().size() == 0) &&
(week.getSundayActivities().size() == 0)) {
RelativeLayout rl = (RelativeLayout) timetable.findViewById(R.id.semesterDay);
rl.removeAllViews();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
rl.addView(View.inflate(timetable.getContext(), R.layout.fragment_layout_timetable_fail, null), params);
} else {
Calendar calendar = Calendar.getInstance();
int day = calendar.get(Calendar.DAY_OF_WEEK);
pager.setAdapter(buildAdapter(res));
if (day == 1) {
int finalDay = 6;
pager.setCurrentItem(finalDay);
} else {
int finalDay = day - 2;
pager.setCurrentItem(finalDay);
}
pager.setOffscreenPageLimit(7);
}
} else {
RelativeLayout rl = (RelativeLayout) timetable.findViewById(R.id.semesterDay);
rl.removeAllViews();
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
rl.addView(View.inflate(timetable.getContext(), R.layout.fragment_layout_fail, null), params);
TextView text = (TextView) timetable.findViewById(R.id.unavailable);
String str = res1.getBody();
int index = str.indexOf("\"}");
text.setText(str.substring(12, index));
}
}
}
Below here is the class for Constants.SERVER_API_URL and Constants.TEST_API_URL
public class Constants {
/* Hosting Setting */
/* Production */
public static final String SERVER_HOST = "Androidmobile.app.com"; //example
public static final String SERVER_API_URL = "https://Androidmobile.app.com/mobile/api";
public static final String SERVER_API_URL_HTTPS = "https://Androidmobile.app.com/mobile/api";
//Testing Dummy Data
public static final String TEST_API_URL = "http://kyawmyohtet.my3gb.com/ExamTimetable.php";
//End Testing
}

Create a constructor in your Asynctask class,
String url = null;
LoadViewTask (String url){
this.url = url;
}
in your onCreate method or wherever you are creating the instance of AsyncTask,
LoadViewTask task1 = new LoadViewTask("Your URL");
you can then use variable url anywhere in your AsyncTask class to access your url.

Below code change in your
private class LoadViewTask extends AsyncTask<Void, Integer, Void> {
to
private class LoadViewTask extends AsyncTask<String, Integer, Void> {
and in doInBackground() method
protected Void doInBackground(String... params)
{
Context ctx = getActivity();
try {
res1 = HttpClient.getCode(ctx, params[0]);
//Testing using with my own Url but not working
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
and call LoadViewTask like below with hardcode url.
SharedPreferences prefs = this.getSharedPreferences(Constants.PREF_NAME, 0);
String str_URL = Constants.TEST_API_URL + "/timetable/semester/" + prefs.getString("Username", "");
new LoadViewTask().execute(str_URL);
this is hardcode URL passed in your LoadViewTask class when and where you call for response.

Related

how do I get the value of a list outside the asynchronous method?

I've done a search on another stackoverflow post for 2 hours but still can not solve this problem. I have a variable called copyAudioListIqro with List String datatype in DetailMemilihIqro Activity class. When the variable called audioIqros in the AsyncTask class (precisely in the onPostExecute method) this list has a value from my json and I want to copy audioIqros variable to copyAudioListIqro via updateData method (outside the asynctask class). When I see the log monitor on updateData method I can see the value from copyAudioListIqro, but the problem is, when I access it via readDataAudioURL method(outside the asynctask class) copyAudioListIqro variable becomes null.
What is the solution for this problem?
Thank you
Here is the overall DetailMemilihIqro class
public class DetailMemilhIqro extends AppCompatActivity {
private ProgressDialog pDialog;
private List<ModelAudioIqro> audioIqros;
private List<String> copyAudioListIqro;
private AudioAdapter mAdapter;
private RecyclerView recyclerView;
private String TAG = DetailMemilihIqro.class.getSimpleName();
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail_memilih_iqro);
recyclerView = (RecyclerView) findViewById(R.id.rvCVAudioIqro);
pDialog = new ProgressDialog(this);
audioIqros = new ArrayList<>();
mAdapter = new AudioAdapter(getApplicationContext(), audioIqros);
context = getApplicationContext();
copyAudioListIqro = new ArrayList<>();
recyclerView.setLayoutManager(new LinearLayoutManager(context));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
Bundle getPosition = getIntent().getExtras();
int position = getPosition.getInt("positionUserClicked");
Log.d(TAG, "Position User clicked " + position);
if (position == 0) {
String endpoint = "http://latihcoding.com/jsonfile/audioiqro1.json";
new DownloadTask().execute(endpoint);
} else if (position == 1) {
String endpoint = "http://latihcoding.com/jsonfile/audioiqro2.json";
new DownloadTask().execute(endpoint);
} else if (position == 2) {
String endpoint = "http://latihcoding.com/jsonfile/audioiqro3.json";
new DownloadTask().execute(endpoint);
}
readDataAudioURL();
}
public void updateData(List<String> pathUrl) {
for (int i = 0; i < pathUrl.size(); i++) copyAudioListIqro.add(pathUrl.get(i));
Log.d(TAG, "updateData Method " + copyAudioListIqro.toString());
}
public void readDataAudioURL() {
Log.d(TAG, "readDataAudioURL Method " + copyAudioListIqro.toString());
}
public class DownloadTask extends AsyncTask<String, Void, List<String>> {
List<String> modelAudioIqroList;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog.setMessage("Downloading json...");
pDialog.show();
}
#Override
protected List<String> doInBackground(String... strings) {
modelAudioIqroList = new ArrayList<>();
int result;
HttpURLConnection urlConnection;
try {
URL url = new URL(strings[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
// 200 represents HTTP OK
if (statusCode == 200) {
BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
response.append(line);
}
parseResult(response.toString());
result = 1; // Successful
Log.d(TAG, "Result " + result);
} else {
//"Failed to fetch data!";
result = 0;
Log.d(TAG, "Result " + result);
}
} catch (Exception e) {
Log.d(TAG, e.getLocalizedMessage());
}
return modelAudioIqroList; //"Failed to fetch data!";
}
#Override
protected void onPostExecute(List<String> audioIqros) {
super.onPostExecute(audioIqros);
pDialog.hide();
if (!audioIqros.isEmpty()) {
updateData(modelAudioIqroList);
} else {
Toast.makeText(context, "Empty", Toast.LENGTH_SHORT).show();
}
}
private void parseResult(String result) {
try {
JSONArray response = new JSONArray(result);
for (int i = 0; i < response.length(); i++) {
JSONObject object = response.getJSONObject(i);
ModelAudioIqro modelAudioIqro = new ModelAudioIqro();
modelAudioIqro.setName(object.getString("name"));
modelAudioIqro.setUrl(object.getString("url"));
String path = modelAudioIqro.getUrl();
Log.d(TAG, "String path " + path);
modelAudioIqroList.add(path);
}
} catch (JSONException e) {
e.printStackTrace();
}
mAdapter.notifyDataSetChanged();
}
}
}
Log for the copyAudioListIqro in the updateDataMethod
Log for the copyAudioListIqro in the readDataAudioURL
readDataAudioURL() call, that is a plain Log call, should be moved. Infact the task is asynch by nature, so oblivously the variable copyAudioListIqro won't have been initialized right after the task's start (.execute() method).
You're doing right, anyway, in notyfiying dataset change to list...You should just move it to postExecute as well...
I suggest to move all "after network" code to that postExecute, so that UI can be updated asynchronously ONLY when data is available and without blocking main thread. You can 'read' variables in the inner class, so just declare them final:
#Override
protected void onPostExecute(List<String> audioIqros) {
super.onPostExecute(audioIqros);
pDialog.hide();
if (!audioIqros.isEmpty()) {
updateData(modelAudioIqroList);
//data is now updated, notify datasets and/or send broadcast
mAdapter.notifyDataSetChanged();
readDataAudioURL();
} else {
Toast.makeText(context, "Empty", Toast.LENGTH_SHORT).show();
}
}
A more elaborate pattern would include broadcast receiver and intents, but I guess this is out of this question's scope.

Swipe Refresh freezes when executing async task

I'm encountering a problem, when I try running an asynchronous task on refresh using a swipe refresh layout it "freezes" and doesn't rotate. When the task is done it just disappears.
Here is my code:
HotActivityFragment.java:
public class HotActivityFragment extends Fragment {
ListView hotList;
SwipeRefreshLayout mSwipeRefreshLayout;
Context context;
SharedPreferences sharedPreferences;
HotListAdapter hotListAdapter;
public HotActivityFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_hot, container, false);
context = getContext();
mSwipeRefreshLayout = (SwipeRefreshLayout)view.findViewById(R.id.activity_main_swipe_refresh_layout);
hotList = (ListView)view.findViewById(R.id.hotListView);
hotList.setOnScrollListener(new EndlessScrollListener(getActivity()));
sharedPreferences = getActivity().getPreferences(Context.MODE_PRIVATE);
try {
ArrayList<ListTypeItem> initial_list = new DownloadPosts(getActivity()).execute().get();
this.hotListAdapter = new HotListAdapter(getContext(), initial_list);
hotList.setAdapter(hotListAdapter);
}catch(Exception e)
{
Log.d("Download Error", e.toString());
}
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
retrievePosts();
}
});
mSwipeRefreshLayout.setColorSchemeResources(R.color.accentColor, R.color.backgroundColor);
return view;
}
public void retrievePosts()
{
// showing refresh animation before making http call
mSwipeRefreshLayout.setRefreshing(true);
//shared preferences = empty
sharedPreferences.edit().putString("last_time_downloaded", "empty").commit();
try {
ArrayList<ListTypeItem> listItems = new DownloadPosts(getActivity(), mSwipeRefreshLayout).execute().get();
hotListAdapter.updateList(listItems);
hotListAdapter.notifyDataSetChanged();
} catch (Exception e) {
Log.d("Download Error", e.toString());
}
mSwipeRefreshLayout.setRefreshing(false);
//for testing purposes
// new Handler().postDelayed(new Runnable() {
// #Override public void run() {
// mSwipeRefreshLayout.setRefreshing(false);
// }
// }, 5000);
}
}
DownloadPosts.java:
public class DownloadPosts extends AsyncTask<Void, Void, ArrayList<ListTypeItem>> {
SharedPreferences sharedPreferences;
SwipeRefreshLayout swipeRefreshLayout;
public DownloadPosts(Activity activity)
{
this.sharedPreferences = activity.getPreferences(Context.MODE_PRIVATE);
}
public DownloadPosts(Activity activity, SwipeRefreshLayout swipeRefreshLayout)
{
this.sharedPreferences = activity.getPreferences(Context.MODE_PRIVATE);
this.swipeRefreshLayout = swipeRefreshLayout;
}
#Override
protected ArrayList<ListTypeItem> doInBackground(Void... args)
{
StringBuilder parsedString = new StringBuilder();
ArrayList<ListTypeItem> downloadList = new ArrayList<>();
StringBuilder str = new StringBuilder();
if(sharedPreferences.getBoolean("Thomas More",false))
{
str.append("190155257998823,");
}
String school_url = str.toString();
if(school_url.length() > 0)
{
school_url = school_url.substring(0, str.length()-1);
}
try{
String date = "";
//checken of opnieuw moet bepaald worden
// + in de adapter moet als gereload wordt last_time_downloaded == empty
if(!sharedPreferences.getString("last_time_downloaded","empty").equals("empty"))
{
String last_date = sharedPreferences.getString("last_time_downloaded","nothing");
last_date = last_date.replace(" ","T");
date= "&datum_last_posted=" + last_date;
}
URL url = new URL("http://localhost/getpostlist.php?school_post=" + school_url + date);
URLConnection conn = url.openConnection();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String json;
while((json = bufferedReader.readLine())!= null)
{
parsedString.append(json + "/n");
}
String s = parsedString.toString().trim();
//converten van string opgehaald via http naar jsonobject
JSONArray array = new JSONArray(s);
for(int i = 0; i < array.length(); i++)
{
JSONObject tempObj = array.getJSONObject(i);
School_WithoutImage tempSchool = new School_WithoutImage(tempObj.getString("school_id"),
tempObj.getString("post_message"),tempObj.getInt("views"),tempObj.getInt("likes")
,tempObj.getInt("post_id"),tempObj.getString("datum_posted"));
downloadList.add(tempSchool);
if(i == array.length()-1) {
sharedPreferences.edit().putString("last_time_downloaded",tempObj.getString("datum_posted")).commit();
}
}
JSONObject obj = array.getJSONObject(0);
}catch(Exception e)
{
Log.d("Exception", e.toString());
}
return downloadList;
}
#Override
protected void onPostExecute(ArrayList<ListTypeItem> result)
{
if(this.swipeRefreshLayout != null)
{
// swipeRefreshLayout.setRefreshing(false);
}
}
}
I have no idea why the swiperefreshview doesn't spin. Anyone has an idea?
Because the call to get():
.execute().get()
Forces the UI thread to wait for the AsyncTask to finish.
Instead you should look at doing this in the onPostExecute method:
protected void onPostExecute(ArrayList<ListTypeItem> listItems) {
hotListAdapter.updateList(listItems);
hotListAdapter.notifyDataSetChanged();
}
Because you are waiting for the result from asynctask by calling get just after execute. And further passing it to list.
You can use Local Broadcast Listener or can create an interface and can us that as callback, without freezing UI

Android widget asynctask

I have an android app with widget which should parse some rss and get some data.
Here is my onReceive method:
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context,intent);
if (intent.getAction().equals(ACTION_TOAST)) {
new RetrieveTask().execute(context);
}
}
And async method itself:
class RetrieveTask extends AsyncTask<Context,Void, List<String>> {
private Exception exception;
private Context context;
private RemoteViews views;
#Override
protected List<String> doInBackground(Context... params) {
List<String> output = new ArrayList<String>();
try {
int k = 15;
doc = Jsoup.connect("http://vlg-media.ru/transport").get();
String img = "";
int i = 0;
Title = doc.select(".art_img");
for (Element titles : Title) {
String IMG = URL;
String HREF;
//Element Img = titles.select(".art_image").first();
IMG = "http://vlg-media.ru" + titles.select("img").attr("src").toString();
IMG = IMG.replace("small", "medium");
HREF = "http://vlg-media.ru" + titles.select("a").attr("href").toString();
// Element Title = titles.select(".con_titlelink").first();
String title = titles.select("img").attr("alt").toString();
m = new HashMap<String, Object>();
m.put(ATTRIBUTE_NAME_TITLE, title);
//добавление данных в наш контейнер
data.add(m);
publishProgress();
i++;
//}
if (i == k)
break;
}
//}
} catch (Exception ex) {
this.exception = ex;
return null;
}
return output;
}
protected void onPostExecute(List<String> output) {
//to make sure it run
Toast.makeText(context,"Done",Toast.LENGTH_LONG).show();
}
}
After doInBackground happens nothing. onPostExecute never run.
I just need to run async parser in my AppWidgetProvider. Don't know where is the problem.
you never assign the Context object. In your case is just
context = params[0];
as first line of doInBackground

Json response is very slow android

I'm writing an Android application which will occasionally need to download a json string of around 1MB and containing around 1000 elements, and parse each of these into an SQLite database, which I use to populate a ListActivity.
Even though the downloading and parsing isn't something that needs to be done on every interaction with the app (only on first run or when the user chooses to refresh the data), I'm still concerned that the parsing part is taking too long, at around two to three minutes - it seems like an eternity in phone app terms!
I am using this code... :-
public class CustomerAsyncTask extends AsyncTask<String, Integer, String> {
private Context context;
private String url_string;
private String usedMethod;
private String identifier;
List<NameValuePair> parameter;
private boolean runInBackground;
AsynTaskListener listener;
private Bitmap bm = null;
public ProgressDialog pDialog;
public String entityUtil;
int index = 0;
public static int retry = 0;
private String jsonString = "";
private String DialogString = "";
// use for AsyncTask web services-----------------
public CustomerAsyncTask(Context ctx, String url, String usedMethod,
String identifier, boolean runInBackground, String DialogString,
List<NameValuePair> parameter, AsynTaskListener callack) {
this.context = ctx;
this.url_string = url;
this.usedMethod = usedMethod;
this.identifier = identifier;
this.parameter = parameter;
this.runInBackground = runInBackground;
this.listener = callack;
this.DialogString = DialogString;
}
public CustomerAsyncTask(Context ctx, String url, String usedMethod,
String identifier, boolean runInBackground,
List<NameValuePair> parameter, AsynTaskListener callack, Bitmap bm) {
this.context = ctx;
this.url_string = url;
this.usedMethod = usedMethod;
this.identifier = identifier;
this.parameter = parameter;
this.runInBackground = runInBackground;
this.listener = callack;
this.bm = bm;
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
if (runInBackground)
initProgressDialog(DialogString);
}
#Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
#SuppressWarnings("deprecation")
#Override
protected String doInBackground(String... params) {
HttpParams httpParameters = new BasicHttpParams();
int timeoutConnection = 10000; // mili second
HttpConnectionParams.setConnectionTimeout(httpParameters,
timeoutConnection);
int timeoutSocket = 10000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
try {
HttpResponse response = null;
if (usedMethod.equals(GlobalConst.POST)) {
HttpPost httppost = new HttpPost(this.url_string);
httppost.setHeader("Content-Type",
"application/x-www-form-urlencoded");
// Customer Login MObile
if (identifier.equals("Customer_Login")) {
if (params.length > 0) {
parameter = new ArrayList<NameValuePair>();
parameter.add(new BasicNameValuePair("cus_mob",
params[0]));
}
httppost.setEntity(new UrlEncodedFormEntity(parameter));
// Customer Verify Code
} else if (identifier.equals("Customer_mob_verify")) {
if (params.length > 0) {
parameter = new ArrayList<NameValuePair>();
parameter.add(new BasicNameValuePair("cus_verify",
params[0]));
parameter.add(new BasicNameValuePair("cus_mobile",
params[1]));
}
httppost.setEntity(new UrlEncodedFormEntity(parameter));
} else if (identifier.equals("Dashboard")) {
if (params.length > 0) {
parameter = new ArrayList<NameValuePair>();
parameter.add(new BasicNameValuePair("cus_id",
params[0]));
}
httppost.setEntity(new UrlEncodedFormEntity(parameter));
}
response = (HttpResponse) httpClient.execute(httppost);
} else if (usedMethod.equals(GlobalConst.GET)) {
HttpGet httpput = new HttpGet(this.url_string);
httpput.setHeader("Content-Type",
"application/x-www-form-urlencoded");
response = (HttpResponse) httpClient.execute(httpput);
}
// Buffer Reader------------------------
InputStream inputStream = null;
String result = null;
try {
HttpEntity entity1 = response.getEntity();
inputStream = entity1.getContent();
BufferedReader reader = new BufferedReader(
new InputStreamReader(inputStream, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
result = sb.toString();
} catch (Exception e) {
} finally {
try {
if (inputStream != null)
inputStream.close();
} catch (Exception squish) {
}
}
jsonString = result;
} catch (ClientProtocolException e) {
e.printStackTrace();
return AsyncResultConst.CONNEERROR;
} catch (IOException e) {
e.printStackTrace();
return AsyncResultConst.CONNEERROR;
} catch (Exception e1) {
e1.printStackTrace();
return AsyncResultConst.EXCEPTION;
} finally {
httpClient.getConnectionManager().shutdown();
}
return AsyncResultConst.SUCCESS;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
if (runInBackground)
pDialog.dismiss();
if (result.equals(AsyncResultConst.SUCCESS)) {
listener.onRecieveResult(identifier, jsonString);
} else if (result.equals(AsyncResultConst.PARSINGERROR)) {
// showAlertMessage(context, "Error", "Parsing Error", null);
listener.onRecieveException(identifier, result);
} else {
if (retry < 0) {
retry++;
new CustomerAsyncTask(context, url_string, usedMethod,
identifier, runInBackground, DialogString, parameter,
listener).execute("");
} else {
// showAlertMessage(context, "Error", "Connection Error", null);
listener.onRecieveException(identifier, result);
}
}
super.onPostExecute(result);
}
private void initProgressDialog(String loadingText) {
pDialog = new ProgressDialog(this.context);
pDialog.setMessage(loadingText);
pDialog.setCancelable(false);
pDialog.show();
}
}
Don't use Async-task in such case, use native java thread here.
new Thread(new Runnable() {
public void run() {
// Do your work .....
}
}).start();
When need to update UI. Yes! Android won't allow you to do that. so... solution is: USE Handler for that :)
Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
// Do Update your UI
}
});
Use AsyncTask for:
Simple network operations which do not require downloading a lot of
data Disk-bound tasks that might take more than a few milliseconds
Use Java threads for:
Network operations which involve moderate to large amounts of data (either uploading or downloading)
High-CPU tasks which need to be run in the background
Any task where you want to control the CPU usage relative to the GUI thread
You could use Google's GSON as well.
Try to use Jackson Library to manage your JSON. It is really efficient. You can find it here : http://mvnrepository.com/artifact/org.codehaus.jackson/jackson-jaxrs
I am using it for a 400KB file is less than 1 second.
If you want a tuto this one looks good http://www.mkyong.com/java/how-to-convert-java-object-to-from-json-jackson/
This is how is read JSON into my listview in my app. The result is processed to my app in an average of 3 seconds on Wi-Fi and 5 seconds on 3G:
public class CoreTeamFragment extends ListFragment {
ArrayList> membersList;
private String url_all_leaders = //URL goes here
private ProgressDialog pDialog;
JSONParser jParser = new JSONParser();
// JSON Node names
private static final String CONNECTION_STATUS = "success";
private static final String TABLE_TEAM = "CoreTeam";
private static final String pid = "pid";
private static final String COL_NAME = "CoreTeam_Name";
private static final String COL_DESC = "CoreTeam_Desc";
private static final String COL_PIC = "CoreTeam_Picture";
JSONArray CoreTeam = null;
public static final String ARG_SECTION_NUMBER = "section_number";
public CoreTeamFragment() {
}
public void onStart() {
super.onStart();
membersList = new ArrayList<HashMap<String, String>>();
new LoadAllMembers().execute();
// selecting single ListView item
ListView lv = getListView();
// Lauching the Event details screen on selecting a single event
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting values from selected ListItem
String ID = ((TextView) view.findViewById(R.id.leader_id))
.getText().toString();
Intent intent = new Intent(view.getContext(),
CoreTeamDetails.class);
intent.putExtra(pid, ID);
view.getContext().startActivity(intent);
}
});
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_coreteam,
container, false);
return rootView;
}
class LoadAllMembers extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Just a moment...");
pDialog.setIndeterminate(true);
pDialog.setCancelable(true);
pDialog.show();
}
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_all_leaders,
"GET", params);
try {
// Checking for SUCCESS TAG
int success = json.getInt(CONNECTION_STATUS);
if (success == 1) {
// products found
// Getting Array of Products
CoreTeam = json.getJSONArray(TABLE_TEAM);
// looping through All Contacts
for (int i = 0; i < CoreTeam.length(); i++) {
JSONObject ct = CoreTeam.getJSONObject(i);
// Storing each json item in variable
String id = ct.getString(pid);
String name = ct.getString(COL_NAME);
String desc = ct.getString(COL_DESC);
String pic = ct.getString(COL_PIC);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(pid, id);
map.put(COL_NAME, name);
map.put(COL_DESC, desc);
map.put(COL_PIC, pic);
// adding HashList to ArrayList
membersList.add(map);
}
} else {
// Options are not available or server is down.
// Dismiss the loading dialog and display an alert
// onPostExecute
pDialog.dismiss();
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
getActivity().runOnUiThread(new Runnable() {
public void run() {
ListAdapter adapter = new SimpleAdapter(
getActivity(),
membersList,
R.layout.coreteam_item,
new String[] { pid, COL_NAME, COL_DESC, COL_PIC },
new int[] { R.id.leader_id, R.id.leaderName,
R.id.photo });
setListAdapter(adapter);
}
});
}
}
}
Use Volley or Retrofit lib.
Those lib are increasing the speed.
Volley:
JsonObjectRequest channels = new JsonObjectRequest(Method.POST,
Constants.getaccountstatement + Constants.key, statement_object,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject arg0) {
}, new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError e) {
Toast.makeText(context, "Error", Toast.LENGTH_SHORT).show();
}

Calling an AsyncTask from another asynctask in doInBackground method?

I have AsyncTask2 called from AsyncTask1... that's my 'scenario':
AsyncTask1 download an rss feed, parse the xml and for every item recognized create&execute AsyncTask2 inside the doInBackground method.
AsyncTask2 in the doInBackground method download the enclosure url attribute of the item passed from AsyncTask1 and in onPostExecute method add the item to the global items array and notify the change of items to the associated adapter.
It works fine and not crashing, why? AsyncTasks are supposed to run from the UI thread (threading rules) and now I'm a little confused about this supposition.
Sorry for bad english, I hope question is clear enough.
EDIT
Here some code...
DownloadRssAsyncTask = AsyncTask2,
RssAsyncTask = AsyncTask1
public class ParseActivity extends Activity {
public class FeedItemAdapter extends ArrayAdapter<FeedItem> {
int resource;
public FeedItemAdapter(Context context, int resource, List<FeedItem> items) {
super(context, resource, items);
this.resource = resource;
}
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout myView;
FeedItem item = getItem(position);
if (convertView == null) {
myView = new LinearLayout(getContext());
String inflaterService = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater li = (LayoutInflater) getContext().getSystemService(inflaterService);
li.inflate(resource, myView, true);
} else {
myView = (LinearLayout) convertView;
}
TextView titleFeedItem = (TextView) myView.findViewById(R.id.itemTitle);
TextView dateFeedItem = (TextView) myView.findViewById(R.id.itemDate);
ImageView imageFeedItem = (ImageView) myView.findViewById(R.id.imageThumb);
titleFeedItem.setText(item.mTitle);
dateFeedItem.setText(item.mPubDate);
imageFeedItem.setImageBitmap(item.bitmapEnclosure);
return myView;
}
}
private class DownloadRssAsyncTask extends AsyncTask<FeedItem, Void, FeedItem> {
#Override
protected FeedItem doInBackground(FeedItem... params) {
FeedItem item = params[0];
if (item.mEnclosure == null) {
Log.i("info: ", "no enclosure tag");
item.bitmapEnclosure = null;
return item;
}
try {
URL imageUrl = new URL(item.mEnclosure);
item.bitmapEnclosure = BitmapFactory.decodeStream(imageUrl.openStream());
} catch (IOException e) {
Log.e("error", "download image resource error: "+item.mEnclosure);
item.bitmapEnclosure = null;
}
return item;
}
#Override
protected void onPostExecute(FeedItem result) {
items.add(result);
arrayAdapter.notifyDataSetChanged();
dbHelper.putItem(result.mGuid, result.mTitle, result.mDescription, result.mEnclosure, result.mPubDate);
}
}
private class RssAsyncTask extends AsyncTask<String, Integer, Void> {
#Override
protected Void doInBackground(String... params) {
int dimParams = params.length;
for (int i=0; i<dimParams; i++) {
Log.i("doInBackground", "rss feed num "+ (i+1) + " of "+ dimParams+ ": " + params[i]);
refreshFeed(params[i]);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
Log.i("onPostExecute in RssAsyncTask", "notifyDataSetChanged");
}
}
public static class FeedItem {
public String mAuthor;
public String mCategory;
public String mComments;
public String mDescription; //r
public String mEnclosure;
public Bitmap bitmapEnclosure;
public String mGuid;
public String mLink; //r
public String mPubDate;
public String mSource;
public String mTitle; //r
public FeedItem() {
// TODO Auto-generated constructor stub
}
#Override
public String toString() {
return
"Data: "+mPubDate+
"\nLink:\n"+mLink+
"\nAutore:\n"+mAuthor+
"\nTitolo:\n"+mTitle+
"\nEnclosure:\n"+mEnclosure;
}
}
private FeedReaderDbHelper dbHelper;
private FeedItemAdapter arrayAdapter;
private ArrayList<FeedItem> items;
private ListView myListView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_parse);
items = new ArrayList<FeedItem>();
new ArrayList<FeedItem>();
myListView = (ListView) findViewById(R.id.myListView);
arrayAdapter = new FeedItemAdapter(this, R.layout.feed_item, items);
myListView.setAdapter(arrayAdapter);
dbHelper = new FeedReaderDbHelper(this);
//RssAsyncTask: download and parsing rss feed
new RssAsyncTask().execute(getString(R.string.my_feed));
}
public void refreshFeed(String feed) {
final String TAG = "refreshFeed";
Log.i(TAG, feed);
URL url = null;
try {
url = new URL(feed);
HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
int httpCode = httpConnection.getResponseCode();
if (httpCode == HttpURLConnection.HTTP_OK) {
processFeed(httpConnection.getInputStream());
} else {
Log.i(TAG, httpCode + httpConnection.getResponseMessage());
}
} catch (MalformedURLException e1) {
Log.i(TAG, "MalformedUrlException in " + feed);
} catch (IOException e) {
Log.i(TAG, "IOException in " + url.toString());
}
}
private void processFeed(InputStream inputStream ) {
final String TAG = "processFeed";
final String ITEM = "item";
final String AUTHOR ="author";
final String TITLE ="title";
final String CATEGORY ="category";
final String COMMENTS ="comments";
final String DESCRIPTION ="description";
final String GUID ="guid";
final String LINK ="link";
final String PUBDATE="pubDate";
final String SOURCE ="source";
final String ENCLOSURE = "enclosure";
Log.i(TAG, inputStream.toString());
XmlPullParserFactory pullParserFact;
try {
pullParserFact = XmlPullParserFactory.newInstance();
pullParserFact.setNamespaceAware(true);
XmlPullParser pullParser = pullParserFact.newPullParser();
pullParser.setInput(inputStream, null);
int eventType = pullParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG && pullParser.getName().equals(ITEM)){
final FeedItem item = new FeedItem();
eventType = pullParser.next();
while ( !(eventType == XmlPullParser.END_TAG && pullParser.getName().equals(ITEM)) ) {
if ( eventType == XmlPullParser.START_TAG ) {
String name = pullParser.getName();
switch (name) {
case AUTHOR:
item.mAuthor = pullParser.nextText();
break;
case TITLE:
item.mTitle = pullParser.nextText();
break;
case CATEGORY:
item.mCategory = pullParser.nextText();
break;
case COMMENTS:
item.mComments = pullParser.nextText();
break;
case DESCRIPTION:
item.mDescription = pullParser.nextText();
break;
case GUID:
item.mGuid = pullParser.nextText();
break;
case LINK:
item.mLink = pullParser.nextText();
break;
case PUBDATE:
item.mPubDate = pullParser.nextText();
break;
case SOURCE:
item.mSource = pullParser.nextText();
break;
case ENCLOSURE:
item.mEnclosure = pullParser.getAttributeValue(null, "url");
default:
break;
}
}
eventType = pullParser.next();
}
//download the optional enclosure resource and update UI
new DownloadRssAsyncTask().execute(item);
}
eventType = pullParser.next();
}
} catch (XmlPullParserException e) {
Log.i(TAG, "XmlPullparserException");
} catch (IOException e) {
Log.i(TAG, "IOException");
}
}
}
Because of the inner workings of AsyncTask.
AsyncTask internally uses a static Handler instance, basically the Android way for thread communication. With a Handler you can send messages and run code on threads; in particular, AsyncTask uses it to run its callbacks such as onPostExecute().
Now, when Handler is initialiazed, it binds on the thread that initializes it. In AsyncTask this is done during class initialization/loading at the line:
private static final InternalHandler sHandler = new InternalHandler();
Since sHandler is also final, it cannot be modified after that, and the callbacks will be always triggered on that thread.
In your case, you create an instance of RssAsyncTask in onCreate(), which is run on the UI thread. This triggers the loading of the AsyncTask class and bind AsyncTask's Handler to the UI thread. Therefore, from that point your onPostExecute()s will always be run on the UI Thread. This is despite you create some AsyncTasks in another background thread.
The Threading Rules want to ensure the class is loaded/initialized on the UI thread (see this) and want to enforce good threading practices.
Also, I recommend IntentService for simple network operations, rather than AsyncTask.

Categories