How to create Async Task to build a RSSReader - java

Before getting down vote. Yes I read the forums before asking this question. RSSReader Async Task
Read that one above but I still don't get it.
The question:
I wrote een RSSReader in Java. This perfectly works in the console prints what I want etc. But in Android it doesn't work because it's not using een Async Task. Now I understood from the Google Documentation that there are three types to be entered AsyncTask something like that. I have no idea how I can implement this in my code. Do I need to make a seperate class extends it with AsyncTask and create and instance of my Reader and in it's doInBackground method call my reader or how do I need to do this.
This is the code of my RSSReader:
public class RSSReader {
//Lists to store headlines, descriptions & images
String url = "http://www.nu.nl/rss/Algemeen";
List<String> titleList;
List<String> descriptionList;
List<String> imageList;
public RSSReader(){
try {
titleList = readRSS(url, "<title>", "</title>");
descriptionList = listFilter(readRSS(url, "<description>", "</description>"), "&nbsp;", "");
imageList = readRSS(url, "<enclosure url \"", "\" length=\"0\" type=\"image/jpeg\"</enclosure>");
}
catch (IOException e){
}
}
public List<String> readRSS(String feedUrl, String openTag, String closeTag) throws IOException, MalformedURLException {
URL url = new URL(feedUrl);
BufferedReader reader= new BufferedReader(new InputStreamReader(url.openStream()));
String currentLine;
List<String> tempList = new ArrayList<String>();
while((currentLine = reader.readLine()) != null){
Integer tagEndIndex = 0;
Integer tagStartIndex = 0;
while (tagStartIndex >= 0){
tagStartIndex = currentLine.indexOf(openTag, tagEndIndex);
if(tagStartIndex >= 0){
tagEndIndex = currentLine.indexOf(closeTag, tagStartIndex);
tempList.add(currentLine.substring(tagStartIndex + openTag.length(), tagEndIndex) + "\n");
}
}
}
tempList.remove(0);
return tempList;
}
public List<String> getDesciptionList(){
return descriptionList;
}
public List<String> getTitleList(){
return titleList;
}
public List<String> getImageList(){
return imageList;
}
public List<String> listFilter(List<String> tempList, String require, String
replace){
//Creates new List
List<String> newList = new ArrayList<>();
//Loops through old list and checks for the 'require' variable
for(int i = 0; i < tempList.size(); i++){
if(tempList.get(i).contains(require)){
newList.add(tempList.get(i).replace(require, replace));
}
else{
newList.add(tempList.get(i));
}
}
return newList;
}
}

In RSSReader#readRSS,you do not check tempList.size()
and do not forget add
<uses-permission android:name="android.permission.INTERNET"/>
to your AndroidManifest.xml
for example
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new RssReaderAsyncTask(new RSSCallBack() {
#Override
public void success(RSSReader rssReader) {
// TODO That Should run on UI Thread if you update UI
// for example
final RSSReader reader = rssReader;
// you can use runOnUiThread or Handler update UI
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Toast
Toast.makeText(MainActivity.this, reader.getTitleList().toString(), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void failed() {
// TODO That Should run on UI Thread if you update UI
Log.e("RSS", "failed");
}
}).execute("");
}
private class RssReaderAsyncTask extends AsyncTask<String, Integer, Integer> {
private RSSCallBack rssCallBack;
public RssReaderAsyncTask(RSSCallBack rssCallBack) {
this.rssCallBack = rssCallBack;
}
#Override
protected Integer doInBackground(String... params) {
// TODO
try {
RSSReader reader = new RSSReader();
rssCallBack.success(reader);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
rssCallBack.failed();
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
rssCallBack.failed();
e.printStackTrace();
}
return null;
}
}
private interface RSSCallBack {
void success(RSSReader rssReader);
void failed();
}
public class RSSReader {
// Lists to store headlines, descriptions & images
String url = "http://www.nu.nl/rss/Algemeen";
List<String> titleList;
List<String> descriptionList;
List<String> imageList;
public RSSReader() throws MalformedURLException, IOException {
titleList = readRSS(url, "<title>", "</title>");
descriptionList = listFilter(readRSS(url, "<description>", "</description>"), "&nbsp;", "");
imageList = readRSS(url, "<enclosure url \"", "\" length=\"0\" type=\"image/jpeg\"</enclosure>");
}
public List<String> readRSS(String feedUrl, String openTag, String closeTag)
throws IOException, MalformedURLException {
URL url = new URL(feedUrl);
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String currentLine;
List<String> tempList = new ArrayList<String>();
while ((currentLine = reader.readLine()) != null) {
Integer tagEndIndex = 0;
Integer tagStartIndex = 0;
while (tagStartIndex >= 0) {
tagStartIndex = currentLine.indexOf(openTag, tagEndIndex);
if (tagStartIndex >= 0) {
tagEndIndex = currentLine.indexOf(closeTag, tagStartIndex);
tempList.add(currentLine.substring(tagStartIndex + openTag.length(), tagEndIndex) + "\n");
}
}
}
if (tempList.size() > 0) {
//TODO you do not check it
tempList.remove(0);
}
return tempList;
}
public List<String> getDesciptionList() {
return descriptionList;
}
public List<String> getTitleList() {
return titleList;
}
public List<String> getImageList() {
return imageList;
}
public List<String> listFilter(List<String> tempList, String require, String replace) {
// Creates new List
List<String> newList = new ArrayList<String>();
// Loops through old list and checks for the 'require' variable
for (int i = 0; i < tempList.size(); i++) {
if (tempList.get(i).contains(require)) {
newList.add(tempList.get(i).replace(require, replace));
} else {
newList.add(tempList.get(i));
}
}
return newList;
}
}
}

You are right, you need Asynctask. But it is too much to explain here, it has already been explained very thoroughly here, so you might wanna take a look:
https://stackoverflow.com/a/9671602/3673616
What you need to make sure is to run your network calls in doInBackground, you can manipulate the UI in onPreExcute and after finish in onpostExecute. For more details please visit the link.

Well i assume that you already know the code so in the doInBackground method should be the long running code, like getting information from internet/server etc. You can then return a string with success or error that will be catched from onPostExecute method, where you can just do what ever you like with the result.
So i would say no need for new class just extend async task in this, implement the 2 methods i mentioned and in the methods call the right function that you already have with just a litttle change for returning result.

Related

Execute Async Task Inside another Async Task

I am trying to call another async task inside an OnPostExecute. The 2nd task does not run at all it seems. I am unable to print anything from within to the logs.
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
JSONObject json = new JSONObject(result);
JSONArray lignes = json.getJSONArray("lignes");
populatelist(lignes);
}
catch (JSONException e) {
}
}
}
The populatelist function fills an array. Inside this function, I try to call the 2nd async task to get values based on this list.
protected void populatelist(JSONArray lignes){
try {
for(int i=0;i<lignes.length(); i++) {
JSONObject jsonas = lignes.getJSONObject(i);
String fdesignation = jsonas.getString("designation");
String fqtecde = jsonas.getString("qtecde");
String fcode_produit = jsonas.getString("code");
InfoStock(fcode_produit);
items.add(new PickingListProduitItem(fdesignation,"",fqtecde, ""));
}
}
catch(Exception e){
}
}
InfoStock() is the function that is used to return additional from a web service.
protected void InfoStock(String code_produit){
String stockURL = "http://" + mSharedPreferences.getString(Constants.SERVER_IP,"")+"//rest/v2/produit/info/code/"+ code_produit + "?stock=true";
try {
if (mDownloader != null && mDownloader.getStatus() == AsyncTask.Status.RUNNING) {
mDownloader.cancel(true);
mPDialog.dismiss();
}
mPDialog = new ProgressDialog(getApplicationContext());
mDownloader = new XMLDownloader(getApplicationContext(),mPDialog);
byte[][] downloadResults = mDownloader.execute(stockURL).get();
// Read stock info.
String s = new String(downloadResults[0], StandardCharsets.UTF_8);
JSONObject resp = new JSONObject(s);
PrixStockJSONParser psj = new PrixStockJSONParser(resp);
mRepInfoStock = psj.getRepInfoStock();
mRepInfoPrix = psj.getRepInfoPrix();
} catch (Exception ex) {
}
}
I am trying to set a value in the array <> created in the OnPostExecute Method. However there is no error message and the array is not populated at all. Even if I try to print a log from the InfoStock function, it does nothing.
Any suggestions are welcome.

javafx ComboBox with cellfactory does not display selected item

I have a small proof of concept app which contains 6 Labels a ComboBox and a Button, all created using SceneBuilder.
By clicking the Button, the app makes a Json api call to return a list of countries and their related details (apla2code, apla3code, name etc). I created a CountryDetails object which holds 3 String elements. I use that to return an array of the CountryDetails which I then load into an array of ObserbavleList. I then apply that to a ComboBox and I load the CountryDetails elements into 3 labels each time an item is selected in the ComboBox. The All of this works fine (although there is probably a much better way of doing this).
The problem I am having is that the ComboBox is not displaying the selected item and I cannot figure out how to correct this. The image below shows what the issue is.
The code which makes the api call is as follows:
import com.google.gson.Gson;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
public class GetCountries {
public CountryDetails[] getDetails() {
String inputLine = "";
StringBuilder jsonString = new StringBuilder();
HttpURLConnection urlConnection;
try {
URL urlObject = new URL("https://restcountries.eu/rest/v2/all");
urlConnection = (HttpURLConnection) urlObject.openConnection();
urlConnection.setRequestMethod("GET");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
while ((inputLine = bufferedReader.readLine()) != null) {
jsonString.append(inputLine);
}
urlConnection.getInputStream().close();
} catch(IOException ioe) {
System.out.println(ioe.getMessage());
}
Countries[] countries = new Gson().fromJson(jsonString.toString(), Countries[].class);
CountryDetails[] countryDetails = new CountryDetails[countries.length];
for(int i = 0; i < countries.length; i++){
countryDetails[i] = new CountryDetails(
countries[i].getAlpha2Code(),
countries[i].getAlpha3Code(),
countries[i].getName()
);
}
return countryDetails;
}
}
The code for the CountryDetails object is as follows:
public class CountryDetails {
private String alpha2Code;
private String alpha3Code;
private String name;
public CountryDetails(String strAlpha2Code, String strAlpha3Code, String strName) {
this.alpha2Code = strAlpha2Code;
this.alpha3Code = strAlpha3Code;
this.name = strName;
}
public String getAlpha2Code() { return alpha2Code; }
public void setAlpha2Code(String alpha2Code) { this.alpha2Code = alpha2Code; }
public String getAlpha3Code() { return alpha3Code; }
public void setAlpha3Code(String alpha3Code) { this.alpha3Code = alpha3Code; }
public String getName() { return name; }
public void setName(String name) {this.name = name; }
}
The code which loads the ObservableList is as follows:
GetCountries countries = new GetCountries();
CountryDetails[] countryDetails = countries.getDetails();
for (CountryDetails countryDetail : countryDetails) {
countriesObservableList.add(new CountryDetails(
countryDetail.getAlpha2Code(),
countryDetail.getAlpha3Code(),
countryDetail.getName())
);
}
The code which loads the ComboBox and displays the elements in the Labels is as follows:
cbCountryList.setCellFactory(new Callback<ListView<CountryDetails>, ListCell<CountryDetails>>() {
#Override public ListCell<CountryDetails> call(ListView<CountryDetails> p) {
return new ListCell<CountryDetails>() {
#Override
protected void updateItem(CountryDetails item, boolean empty) {
super.updateItem(item, empty);
if (empty || (item == null) || (item.getName() == null)) {
setText(null);
} else {
setText(item.getName());
}
}
};
}
});
public void comboAction(ActionEvent event) {
lblAlpha2Code.setText(cbCountryList.getValue().getAlpha2Code());
lblAlpha3Code.setText(cbCountryList.getValue().getAlpha3Code());
lblCountryName.setText(cbCountryList.getValue().getName());
}
Below is the image of the app:
The problem I am having is that the ComboBox is not displaying the selected item and I cannot figure out how to correct this.
You need to set a StringConverter for your cbCountryList.
cbCountryList.setConverter(new StringConverter<CountryDetails>() {
#Override
public String toString(CountryDetails object) {
return object.getName();
}
#Override
public CountryDetails fromString(String string) {
return null;
}
});
The All of this works fine (although there is probably a much better way of doing this).
You may consider updating the following things,
Asynchronous call for HTTP request and load items
You can cache your fetched-country list as you're calling every time when the button gets triggered. You can make a Singleton object for GetCountries.
Modified GetCountries class,
It caches the countries list and uses the cached data for multiple requests,
public static class GetCountries {
private static final String API_URL = "https://restcountries.eu/rest/v2/all";
private static CountryDetails[] countryDetails;
public static CountryDetails[] getDetails() {
//uses cached countryDetails once it gets loaded
if (countryDetails != null) {
return countryDetails;
}
StringBuilder jsonString = new StringBuilder();
HttpURLConnection urlConnection;
try {
URL urlObject = new URL(API_URL);
urlConnection = (HttpURLConnection) urlObject.openConnection();
urlConnection.setRequestMethod(HttpMethod.GET.name());
String inputLine = "";
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
while ((inputLine = bufferedReader.readLine()) != null) {
jsonString.append(inputLine);
}
urlConnection.getInputStream().close();
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
Countries[] countries = new Gson().fromJson(jsonString.toString(), Countries[].class);
countryDetails = new CountryDetails[countries.length];
for (int i = 0; i < countries.length; i++) {
countryDetails[i] = new CountryDetails(
countries[i].getAlpha2Code(),
countries[i].getAlpha3Code(),
countries[i].getName()
);
}
return countryDetails;
}
}
Use Task to fetch your countries asynchronously,
Task<CountryDetails[]> fetchCountryTask = new Task<CountryDetails[]>() {
#Override
protected CountryDetails[] call() throws Exception {
return GetCountries.getDetails();
}
};
fetchButton.setOnAction(event -> new Thread(fetchCountryTask).start());
fetchCountryTask.setOnRunning(event -> cbCountryList.setDisable(true));
fetchCountryTask.setOnSucceeded(e -> {
cbCountryList.getItems().addAll(fetchCountryTask.getValue());
cbCountryList.setDisable(false);
});

Unable to access current value of Global Variable in Java

Below is my code, lat_val and long_val is not getting updated with received value from JSON response in btnShowLoc(), it is referencing to the default value which is 0,0. I want the global variable to keep updating when ever referenced and updated with JSON response.
public class MainActivity extends Activity {
public static String lat_val = "0";
public static String long_val = "0";
public String readJSONFeed(String urlStr) {
StringBuilder stringBuilder = new StringBuilder();
try {
URL url = new URL(urlStr);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestProperty("SisApiKey", "4572c3c9-73cb-4958-9649-26c1e8df27e8");
urlConnection.setRequestProperty("SisSmartKey", "d1aebd25-774c-4e8a-b3a5-ee5a603cc603");
InputStream ins = urlConnection.getInputStream();
urlConnection.connect();
int statusCode = urlConnection.getResponseCode();
if (statusCode == 200) {
BufferedReader br = new BufferedReader(new InputStreamReader(ins));
String line;
while ((line = br.readLine()) != null) {
stringBuilder.append(line);
}
ins.close();
} else {
Log.d("JSON", "Failed to download file");
}
} catch (java.net.MalformedURLException e) {
e.printStackTrace();
} catch (java.io.IOException e) {
e.printStackTrace();
} catch (Exception e) {
Log.d("readJSONFeed", e.getLocalizedMessage());
}
return stringBuilder.toString();
}
public class ReadJSONFeedTask extends AsyncTask
<String, Void, String> {
protected String doInBackground(String... url) {
return readJSONFeed(url[0]);
}
protected void onPostExecute(String result) {
try {
JSONObject jsonObject = new JSONObject(result);
//JSONObject flags = new JSONObject(jsonObject.getString("flag"));
JSONObject locationItems = new JSONObject(jsonObject.getString("response"));
//Log.v("Location Details :", locationItems.toString());
String []dev_loc = locationItems.toString().split("[\\s*,\\s*]");
MainActivity.lat_val = dev_loc[0]; //"12.9934136";
MainActivity.long_val = dev_loc[1]; //"80.2464206";
} catch (Exception e) {
Log.d("ReadJSONFeedTask", e.getLocalizedMessage());
}
}
}
public void btnGetDevLoc(View view) {
String sp_val = String.valueOf(spinner1.getSelectedItem());
new ReadJSONFeedTask().execute(
"http://15.153.133.160:21743/sis/sie/api/v1/applications/bb9f05fb-a796-4b75-9db7-c999360ad185/virtualobjects/d77d3905-aa77-41b9-9034-b0052bfde405?secondString=HWE_ASSET_ANDROID"); // + sp_val);
}
public void btnShowLoc(View view) {
//lat_val = "12.9934136";
//long_val = "80.2464206";
Intent in = new Intent(MainActivity.this, MapActivity.class);
Bundle bundle = new Bundle();
bundle.putString("latitude", MainActivity.lat_val);
bundle.putString("longitude", MainActivity.long_val);
in.putExtras(bundle);
startActivity(in);
}
With the few information you have shared, and given that
btnGetDevLoc() and btnShowLoc()are the functions executed when clicked on buttons in the application defined in activity_main.xml
and that
First btnGetDevLoc() is called then btnShowLoc()
the first thing that pops out in my mind is that the AsyncTask has not yet finished updating the String values, when you call btnShowLoc().
So, if btnGetDevLoc() and btnShowLoc() are called sequentially, like
... onClick() {
btnGetDevLoc();
btnShowLoc();
}
then it's most likely due to what I said above. Remember that AsyncTask runs asynchronously (as the name says...).
You can test this really small program.
public static double var1 = 0.0;
public static void main(String[] args) {
new Thread(() -> {
var1 = 1.0;
}).start();
System.out.println(var1);
}
It will almost always print 0.0, because the value of var1 is not updated yet when the main thread prints it.
What you should do is place your btnShowLoc() call at the end of onPostExecute(String). This guarantees that your method is called only after you have updated the new values.
I can't Understand, when the btnGetDevLoc() and btnShowLoc() called? Can you post your whole MainActivity?
Edit :
It's seems like you call btnShowLoc() before your AsyncTask finish its proccess.
You can change your code this way to make sure your btnShowLoc() called after your AsyncTask :
public class ReadJSONFeedTask extends AsyncTask
<String, Void, String> {
protected String doInBackground(String... url) {
return readJSONFeed(url[0]);
}
protected void onPostExecute(String result) {
try {
JSONObject jsonObject = new JSONObject(result);
//JSONObject flags = new JSONObject(jsonObject.getString("flag"));
JSONObject locationItems = new JSONObject(jsonObject.getString("response"));
//Log.v("Location Details :", locationItems.toString());
String []dev_loc = locationItems.toString().split("[\\s*,\\s*]");
MainActivity.lat_val = dev_loc[0]; //"12.9934136";
MainActivity.long_val = dev_loc[1]; //"80.2464206";
btnShowLoc(dev_loc[0], dev_loc[1]);
} catch (Exception e) {
Log.d("ReadJSONFeedTask", e.getLocalizedMessage());
}
}
}
public void btnShowLoc(String latitude, String longitude) {
//lat_val = "12.9934136";
//long_val = "80.2464206";
Intent in = new Intent(MainActivity.this, MapActivity.class);
Bundle bundle = new Bundle();
bundle.putString("latitude", latitude);
bundle.putString("longitude", longitude);
in.putExtras(bundle);
startActivity(in);
}

Passing List<classname> to ArrayAdapter

The problem is this adapter is giving the error although i have pass the Object array to it.(Read the methods belows then you will find what i want to know from you guys)
This method declares a List of private class objects. Then return that list of object to onPostExecute method.
private class DownloadXmlTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
try {
return loadXmlFromNetwork(urls[0]);
} catch (IOException e) {
return "I/O exception ae hy";
} catch (XmlPullParserException e) {
return "XML pull parser ke exception ae hy";
}
}
#Override
protected void onPostExecute(List<StackOverflowXmlParser.Entry> result) {
//Log.d(TAG,result.toString());
ArrayAdapter<String> adapter;
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,result);
setListAdapter(adapter);
}
private Object loadXmlFromNetwork(String urlString) throws XmlPullParserException, IOException {
InputStream stream = null;
// Instantiate the parser
StackOverflowXmlParser stackOverflowXmlParser = new StackOverflowXmlParser();
List<StackOverflowXmlParser.Entry> entries = null;
String title = null;
String url = null;
String summary = null;
try {
stream = downloadUrl(urlString);
entries = stackOverflowXmlParser.parse(stream);
} finally {
if (stream != null) {
stream.close();
}
}
for (StackOverflowXmlParser.Entry entry : entries)
{
Log.d(TAG, entry.link + " /" + entry.title);
}
return entries;
}
I think it should be onPostExecute(List<StackOverflowXmlParser.Entry> result)
And you AsyncTask should be
extends AsyncTask<smth, smth, List<StackOverflowXmlParser.Entry> >
ArrayAdapter<String> requires that you provide it a String[] or a List<String>. You are trying to pass in Object[], which is neither String[] nor List<String>. And, it would appear that you are really trying to populate the ListView with a list of StackOverflowXmlParser.Entry objects, which are not String objects.
My guess is that the right answer is for you to create an ArrayAdapter<StackOverflowXmlParser.Entry> instead of an ArrayAdapter<String>.
Regardless, you need to ensure that the data type in your declaration (String in ArrayAdapter<String>) matches the data type in your constructor parameter that supplies the data to be adapted.

Return data from AsyncTask class

How do I get the data from my AsyncTask? My MainActivity is calling the DataCall.getJSON function that triggers the AsyncTask but I am not sure how to get the data back to the original Activity.
MainActivity with call to DataCall that should return a string and save it in state_data
String state_data = DataCall.getJSON(spinnerURL,spinnerContentType);
DataCall:
public class DataCall extends Activity {
private static final String TAG = "MyApp";
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(
new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
protected void onPostExecute(String result) {
//THIS IS WHERE I NEED TO RETURN MY DATA TO THE MAIN ACTIVITY. (I am guessing)
}
}
public void getJSON(String myUrlString, String contentType) {
DownloadWebPageTask task = new DownloadWebPageTask();
task.execute(new String[] { "http://www.mywebsite.com/" + myUrlString });
}
}
modify your AsyncTask as below:
public class GetData extends AsyncTask<String, Void, String>
{
DataDownloadListener dataDownloadListener;
public GetData()
{
//Constructor may be parametric
}
public void setDataDownloadListener(DataDownloadListener dataDownloadListener) {
this.dataDownloadListener = dataDownloadListener;
}
#Override
protected Object doInBackground(Object... param)
{
// do your task...
return null;
}
#Override
protected void onPostExecute(Object results)
{
if(results != null)
{
dataDownloadListener.dataDownloadedSuccessfully(results);
}
else
dataDownloadListener.dataDownloadFailed();
}
public static interface DataDownloadListener {
void dataDownloadedSuccessfully(Object data);
void dataDownloadFailed();
}
}
and use it in your Activity
GetData getdata = new GetData();
getdata.setDataDownloadListener(new DataDownloadListener()
{
#SuppressWarnings("unchecked")
#Override
public void dataDownloadedSuccessfully(Object data) {
// handler result
}
#Override
public void dataDownloadFailed() {
// handler failure (e.g network not available etc.)
}
});
getdata.execute("");
NOTE: For the people who are reading this.
Please consider this post for the best and perhaps right implementation.
The key for me was to create a class called URLWithParams or something because AsyncTask will allow only 1 type to be sent IN, and I needed both the URL and the params for the HTTP request.
public class URLWithParams {
public String url;
public List<NameValuePair> nameValuePairs;
public URLWithParams()
{
nameValuePairs = new ArrayList<NameValuePair>();
}
}
and then I send it to a JSONClient:
public class JSONClient extends AsyncTask<URLWithParams, Void, String> {
private final static String TAG = "JSONClient";
ProgressDialog progressDialog ;
GetJSONListener getJSONListener;
public JSONClient(GetJSONListener listener){
this.getJSONListener = listener;
}
#Override
protected String doInBackground(URLWithParams... urls) {
return connect(urls[0].url, urls[0].nameValuePairs);
}
public static String connect(String url, List<NameValuePair> pairs)
{
HttpClient httpclient = new DefaultHttpClient();
if(url == null)
{
Log.d(TAG, "want to connect, but url is null");
}
else
{
Log.d(TAG, "starting connect with url " + url);
}
if(pairs == null)
{
Log.d(TAG, "want to connect, though pairs is null");
}
else
{
Log.d(TAG, "starting connect with this many pairs: " + pairs.size());
for(NameValuePair dog : pairs)
{
Log.d(TAG, "example: " + dog.toString());
}
}
// Execute the request
HttpResponse response;
try {
// Prepare a request object
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(pairs));
response = httpclient.execute(httpPost);
// Examine the response status
Log.i(TAG,response.getStatusLine().toString());
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
String json = reader.readLine();
return json;
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String json ) {
getJSONListener.onRemoteCallComplete(json);
}
public interface GetJSONListener {
public void onRemoteCallComplete(String jsonFromNet);
}
}
Then call it from my main class like this
public class BookCatalog implements GetJSONListener {
private final String TAG = this.getClass().getSimpleName();
private String catalog_url = "URL";
private void getCatalogFromServer() {
URLWithParams mURLWithParams = new URLWithParams();
mURLWithParams.url = catalog_url;
try {
JSONClient asyncPoster = new JSONClient(this);
asyncPoster.execute(mURLWithParams);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Override
public void onRemoteCallComplete(String jsonBookCatalogList) {
Log.d(TAG, "received json catalog:");
Log.d(TAG, jsonBookCatalogList);
JSONObject bookCatalogResult;
try {
bookCatalogResult = (JSONObject) new JSONTokener(jsonBookCatalogList).nextValue();
JSONArray books = bookCatalogResult.getJSONArray("books");
if(books != null) {
ArrayList<String> newBookOrdering = new ArrayList<String>();
int num_books = books.length();
BookCatalogEntry temp;
DebugLog.d(TAG, "apparently we found " + Integer.toString(num_books) + " books.");
for(int book_id = 0; book_id < num_books; book_id++) {
JSONObject book = books.getJSONObject(book_id);
String title = book.getString("title");
int version = book.getInt("price");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Although i disagree creating a new activity for that simple task there is
startActivityForResult()
to get data from another activity.
Check this. You can store your data to the Intent's extras. But still if you have a large amount of data you better off write it to a file get the result from the other activity that is done downloading and then read the file.
Serialize it and then read it. The only way I'm aware of.
Some options:
a) Make your bean implement Serializable interface, you can then pass your bean through Intent.
b) Implement Application interface (you need to make an entry in manifest), Have setter\getter method in your Application class. You can set your bean in Application from AsyncTask and later retrieve from Activity.
Sorry for answering so late, i think by this time you might have solved this problem. when i was searching for something else, i came across your question. I'm pasting a link here which might of some help for others.

Categories