Make onPreExecute and onProgressUpdate common for all Asynctask Class - java

Currently , I am working in android application , in that I have 10 separate Asynctask Class for 10 separate operation , in that , the user defined function called inside onPreExecute() and onProgressUpdate() will be same for all 10 Asynctask Class. Is there any other way to simplify this . For example , I have an user defined function named "ADD" , and as of now , I have called the "ADD" function in onPreExecute() of all 10 Asynctask Class , is there any other way to simplify this , by using interface or any-other else,

Create One Class that is BaseAsyncTask which extends AsyncTask.
And write implementation of your both onPreExecute() and onProgressUpdate() int this.
public abstract class BaseAsyncTask<Params, Progress, Result> extends AsyncTask<Params, Progress, Result> {
#android.support.annotation.Nullable
private ProgressDialog progressDialog = null;
public Activity activity;
public BaseAsyncTask(Activity activity) {
this.activity = activity;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(activity, R.style.CustomProgressSpinner);
CommonUtilities.showDialog(progressDialog,activity);
}
#Override
protected void onProgressUpdate(Progress... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Result result) {
super.onPostExecute(result);
CommonUtilities.dismissDialog(progressDialog);
}
}
And in extend that BaseAsyncTask in your all AsyncTask.
public class AttachmentLoadTask extends BaseAsyncTask<DocumentVO, Void, File> {#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected File doInBackground(DocumentVO... documentVOs) {
File file = null;
return file;
}
#Override
protected void onProgressUpdate(Progress... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(File file) {
super.onPostExecute(file);
}}

Create a basic async task with the operations in onPreExecute() and onProgressExecute(). Then create your async task classes (extend from the basic async task).

surely , you may create a single class for all Asynctask calls
just create a class
public class MyConnectionClass extends AsyncTask<Uri, Void, Boolean> {
MyAsyncInterface delegate = null;
HttpURLConnection httpURLConnection;
String output;
public MyConnectionClass(MyAsyncInterface myAsyncInterface) {
delegate = myAsyncInterface;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(Boolean aBoolean) {
delegate.processFinish(output);
super.onPostExecute(aBoolean);
}
#Override
protected Boolean doInBackground(Uri... uris) {
try {
URL url = new URL(uris[0].toString());
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
httpURLConnection.setRequestMethod("POST");
httpURLConnection.connect();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
String line = null;
StringBuilder builder = new StringBuilder();
while ((line = reader.readLine()) != null) {
builder.append(line);
}
output = builder.toString();
return true;
} catch (MalformedURLException e) {
output = e.getMessage();
return false;
} catch (IOException e) {
output = e.getMessage();
return false;
} finally {
httpURLConnection.disconnect();
}
}
}
and declare an interface like this
public interface MyAsyncInterface {
void processFinish(String output);
}
then create a Uri in your activity and implement MyAsyncInterface then inside the onPostExecute call processFinish and pass the output to the processFinish(String output) method present in your calling activity

Related

Change TextView Between Activities

So i got a project with the following activities : MainActivity/GetJson/ TimerActivity.
GetJson activity :
public class GetJson extends AppCompatActivity {
String JSON_STRING;
String json;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void getJSON(View view){
new BackgroundTask().execute();
}
public class BackgroundTask extends AsyncTask<Void,Void,String> {
String json_url;
#Override
protected void onPreExecute() {
json_url="http://10.10.103.36/projet/php/fichier.php";
}
#Override
protected String doInBackground(Void... params) {
try {
URL url=new URL(json_url);
HttpURLConnection httpURLConnection=(HttpURLConnection)url.openConnection();
InputStream inputStream=httpURLConnection.getInputStream();
BufferedReader bufferedReader=new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder=new StringBuilder();
while ((JSON_STRING= bufferedReader.readLine())!=null){
stringBuilder.append(JSON_STRING+"\n");
}
bufferedReader.close();
inputStream.close();;
httpURLConnection.disconnect();
return stringBuilder.toString().trim();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result) {
json=result;
}
}
}
Timer Activity
public class TimerActivity extends Activity {
private TextView test;
String msg = "Hey";
private Handler mHandler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
test = (TextView) findViewById(R.id.compteur);
Timer timer = new Timer();
TimerTask tt = new TimerTask()
{
#Override
public void run()
{
test.setText(msg);
}
};
timer.scheduleAtFixedRate(tt,5000,1000); // Delay 5 seconds on the first run
// then run every second
test.setText(msg);
setContentView(R.layout.activity_main);
}
}
In my xml main activity i got 2 textview :
- compteur : to display a text from my timeractivity
- textViewJson : to display my json
I think my methods to get json( from GetJson) and display text(from TimerActivity) are correct. But the problem is that i can't setText from others activities to my main activity.
I don't have any compilation problem bu my textView aren't getting updated.
I tried both in GetJson and TimerActivity to just do :
TextView test;
test = (TextView) findViewById(R.id.compteur);
test.setText(msg);
In order to check if i can change the textview text without even using the returned values and nothing happens.
Any ideas ?
Have a good day !
Once you have the information you want to show in your TVs you should save it somewhere and load it when your Activity is created. You can't change the state of Views in a destroyed Activity. Use Intents (putExtra();) to pass data between your Activies or use SharedPreferences

onPostExecute is not called

So I am having issues with my AsyncTask. I need postExecute to display an alert dialog if a certain error throwable is caught in doInBackground. The problem is that postExecute is never called. I have tried adding #Override but Android Studio says that it isn't overriding a method in its super class. I have also tried changing the return type. I looked around this site and couldn't find an answer. Thanks in advance.
AsyncTask Class
public class AsyncTaskActivity extends AsyncTask<Void, Void, Void> {
String exception;
#Override
protected void onPreExecute() {
}
protected void onPostExecute() {
if (exception.contains("java.net.UnknownHostException")) {
MainActivity.showDialog();
Log.i("Error Message", "ERROR MESSAGE SHOWN");
}
}
#Override
protected Void doInBackground(Void... params) {
try {
Log.i("AsyncTask", "Loading...");
// Make a URL to the web page. This takes the string representation of the URL
// and changes it into a URL object
URL url = new URL("http://api.wunderground.com/api/0c0fcc3bf62ab910/conditions/q/IN/Fort_Wayne.json");
// Get the input stream through URL Connection
URLConnection con = url.openConnection();
InputStream is = con.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line;
// read each line and write to text file
while ((line = br.readLine()) != null) {
Log.i("AsyncTask", line);
TextEditor.file = new File(MainActivity.path, "siteInfo.txt");
TextEditor.writeString(line);
}
TextEditor.saveAndClose();
} catch (Exception e) {
e.printStackTrace();
exception = e.toString();
}
Log.i("AsyncTask", "DONE");
return null;
}
}
showDialog method
public static void showDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.context);
builder.setView(R.layout.dialog_layout);
builder.setPositiveButton(
R.string.dialog_close,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
System.exit(1);
}
});
builder.show();
}
look like you're missing something
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if (exception.contains("java.net.UnknownHostException")) {
MainActivity.showDialog();
Log.i("Error Message", "ERROR MESSAGE SHOWN");
}
}
First please refer this documentation. you have missed parameters on onPostExecute().
https://developer.android.com/reference/android/os/AsyncTask.html
What you would have to do is,
#Override
protected void onPostExecute(Params) {
// your logics
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if (exception.contains("java.net.UnknownHostException")) {
MainActivity.showDialog();
Log.i("Error Message", "ERROR MESSAGE SHOWN");
}
}
Please note that you need to initialize exception, otherwise it may cause a NullPointerException

Getting an Arraylist from an inner AsyncTask class

I've parsed some XML Data in Asynctask and printed it in the log, but whenever I try to copy the ArrayList of data into my Activity, it always remains null.
Here's the code,
public class MainActivity extends AppCompatActivity {
static ArrayList<NewsItems>myData=new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ReadRss readRss = new ReadRss(this);
readRss.execute();
Log.d("TAG", String.valueOf(myData.size()));//This stays empty
}
public static void getData(ArrayList<NewsItems>items){
for (int i=0; i<items.size(); i++){
myData.add(items.get(i));
}
}
class ReadRss extends AsyncTask<Void, Void, Void>{
ArrayList<NewsItems>feedItems = new ArrayList<>();
Context context;
String address = "http://www.thedailystar.net/frontpage/rss.xml";
ProgressDialog progressDialog;
URL url;
public ReadRss(Context context) {
this.context = context;
progressDialog = new ProgressDialog(context);
progressDialog.setMessage("Loading...");
}
#Override
protected void onPreExecute() {
if(progressDialog!=null){
if (!progressDialog.isShowing()){
progressDialog.show();
}
}
super.onPreExecute();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(progressDialog!=null){
if (progressDialog.isShowing()){
progressDialog.hide();
}
}
MainActivity.getData(feedItems);
}
#Override
protected Void doInBackground(Void... params) {
ProcessXml(Getdata());
return null;
}
private void ProcessXml(Document data) {
if (data != null) {
Element root = data.getDocumentElement();
Node channel = root.getChildNodes().item(1);
NodeList items = channel.getChildNodes();
for (int i = 0; i < items.getLength(); i++) {
Node currentchild = items.item(i);
if (currentchild.getNodeName().equalsIgnoreCase("item")) {
NewsItems item=new NewsItems();
NodeList itemchilds = currentchild.getChildNodes();
for (int j = 0; j < itemchilds.getLength(); j++) {
Node current = itemchilds.item(j);
if (current.getNodeName().equalsIgnoreCase("title")){
item.setTitle(current.getTextContent());
}else if (current.getNodeName().equalsIgnoreCase("description")){
item.setDescription(current.getTextContent());
}else if (current.getNodeName().equalsIgnoreCase("media:thumbnail")){
item.setMedia(current.getAttributes().getNamedItem("url").getTextContent());
}else if (current.getNodeName().equalsIgnoreCase("link")){
item.setUrl(current.getTextContent());
}
}
feedItems.add(item);
Log.d("itemTitle", item.getTitle());
Log.d("itemDescription",item.getDescription());
Log.d("itemMediaLink",item.getMedia());
Log.d("itemLink",item.getUrl());
}
}
}
}
public Document Getdata() {
try {
url = new URL(address);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
InputStream inputStream = connection.getInputStream();
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document xmlDoc = builder.parse(inputStream);
return xmlDoc;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
}
I tried calling a static method of the Activity in the onPostExecute method, it doesn't work.
1) You should declare the ArrayList variable as a member of mainActivity and then pass its reference into the Asynctask.
2) You can verify that the data is present in the list, only after you are sure the Asynctask has completed processing. (You can do that within the onPostExecute of the AsyncTask).
public class MainActivity extends AppCompatActivity {
ArrayList<NewsItems>myData=new ArrayList<>(); //No need for static
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ReadRss readRss = new ReadRss(this,myData); //Pass the list variable reference into the asynctask instance
readRss.execute();
Log.d("TAG", String.valueOf(myData.size()));//This will be empty due to concurrent call to asynctask, which executes parallel to main thread.
}
public void getData(ArrayList<NewsItems>items){//Static qualifier unneccessary here
for (int i=0; i<items.size(); i++){
myData.add(items.get(i));
}
}
class ReadRss extends AsyncTask<Void, Void, Void>{
ArrayList<NewsItems>feedItems = new ArrayList<>();
Context context;
String address = "http://www.thedailystar.net/frontpage/rss.xml";
ProgressDialog progressDialog;
URL url;
public ReadRss(Context context,ArrayList<NewsItems> feedItems) {
this.context = context;
this.feedItems = feedItems; //Assign the reference of the list here so that modifications done within the Asynctask are reflected in the MainActivity
progressDialog = new ProgressDialog(context);
progressDialog.setMessage("Loading...");
}
#Override
protected void onPreExecute() {
if(progressDialog!=null){
if (!progressDialog.isShowing()){
progressDialog.show();
}
}
super.onPreExecute();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(progressDialog!=null){
if (progressDialog.isShowing()){
progressDialog.hide();
}
}
//Do whatever you need with the arraylist data here
getData(feedItems);
}
#Override
protected Void doInBackground(Void... params) {
ProcessXml(Getdata());
return null;
}
Avoid static variables as much as possible. Unnecessary static fields land you into problems hard to understand.
If you are populating it in an AdapterView like ListView, remember to call adapter.notifyDataSetChanged() when you have the data set ready with you.
You can actually pass the result of your doInBackground() to onPostExecute() to continue doing your work on the calling thread, which is the main thread in your case.
new AsyncTask<Void, Void, ArrayList<NewsItems>>() {
#Override
protected ArrayList<NewsItems> doInBackground(Void... params) {
ArrayList<NewsItems> response = whatEverMethodGetsMeNetworkCallResponse();
return response;
}
#Override
protected void onPostExecute(ArrayList<NewsItems> response) {
super.onPostExecute(response);
// Do whatever you want to do with the network response
}
}.execute();
Or you can even set up listeners and do it in a more sophisticated way like:
onCreate() {
...
getNewsItems(new NewsItemsListener() {
void onFetched(ArrayList<NewsItems> items) {
// Do whatever you want to do with your news items
}
});
}
public void getNewsItems(final NewsItemsListener listener)
new AsyncTask<Void, Void, ArrayList<NewsItems>>() {
#Override
protected ArrayList<NewsItems> doInBackground(Void... params) {
ArrayList<NewsItems> response = whatEverMethodGetsMeNetworkCallResponse();
return response;
}
#Override
protected void onPostExecute(ArrayList<NewsItems> response) {
super.onPostExecute(response);
listener.onFetched(response);
}
}.execute();
}
public interface NewsItemsListener {
void onFetched(ArrayList<NewsItems> items);
}

AsyncTask onPostExecute listener [duplicate]

This question already has answers here:
how to return result from asyn call
(2 answers)
Closed 7 years ago.
Activity.java
//Activity stuff
MyClass mc = new MyClass();
mc.getText();
public void dosomething() {
textview.setText(mc.getText());
}
MyClass.java
class MyClass {
String text;
public void setText() {
class GetTextFromWEB extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String url = urls[0];
String output;
//Getting text from web
return output;
}
#Override
protected void onPostExecute(String _text) {
text = _text;
}
}
String url = "google.com";
//Doing with url something
new GetText().execute(url);
}
public String getText() {return text;}
}
Promblem is - in activity setText do faster, then AsyncTask do it's job.
So when setText run, it's run like setText(null)
I need to check in activity, is asynk ended, so i have my text to set.
I hope i explained it
And i don't even need exactly AsyncTask, i need jsoup working, so if there is solution with another thread-class, with which jsoup will work, i can use it
Edit
class GetLyrics extends AsyncTask<String, Void, String> { //Class for getting lyrics
private Context con;
public GetLyrics(Context con) {
this.con = con;
}
#Override
protected String doInBackground(String... urls) {
//do something
}
#Override
protected void onPostExecute(String _lyrics) {
lyrics = _lyrics;
con.runOnUiThread(new Runnable() {
#Override
public void run() {
((TextView) findViewById(R.id.lyricsOutput)).setText(lyrics);
}
});
}
}
Call the method setting your text in the postExecute inside your AsyncTask or set the text directly on your postExecute method.
And wrap the line with setText() inside runOnUIThread (otherwise you will get an exception saying that the view can be accessed only by the thread that created it, since you are setting the text from async task).
Setting the text would be something like this
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
((TextView) findViewById(R.id.txtFieldName)).setText("your text");
}
});
That way you can quit worrying about checking if the async task is finished. But avoid doing complex ui operations like this. Since this is just setting the text on TextView, it should be allright.
1: Make my first project from my previous post and add some new lines in it to get data from http: api's.
public class Example extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_example);
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("parameter1", "xyz"));
params.add(new BasicNameValuePair("parameter2", "abc"));
params.add(new BasicNameValuePair("parameter3", "opqr"));
ServerConnection task = new ServerConnection(this, new ResultListener() {
#Override
public void result(String response) {
Toast.make(this, response, Toast.LENGTH_LONG).show();
}
#Override
public void loader(boolean visble) {
}
#Override
public void connectionLost(String error) {
Toast.make(this, error, Toast.LENGTH_LONG).show();
}
});
}
public class ServerConnection extends AsyncTask<String, String, String> implements Constant {
ResultListener listener;
private String Method = "GET";
private List<NameValuePair> params = new ArrayList<NameValuePair>();
private Context context;
private ConnectionDetector cd;
// public static Drawable drawable;
public ServerConnection(Context context, ResultListener r) {
this.context = context;
this.listener = r;
cd = new ConnectionDetector(context);
this.execute();
}
public boolean isConnection() {
return cd.isConnectingToInternet();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... arg0) {
if (!isConnection()) {
cancel(true);
return "Sorry!connection lost,try again or later";
}
ApiResponse air = new ApiResponse();
System.out.println("working hre" + "hi");
String json;
try {
json = air.makeHttpRequest(URL, getMethod(), getParams());
} catch (Exception e) {
json = e.getMessage();
cancel(true);
return json;
}
return json;
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#Override
protected void onCancelled(String result) {
listener.connectionLost(result);
rl.connectionLost("Sorry!connection lost,try again or later");
super.onCancelled(result);
}
#Override
protected void onPostExecute(String result) {
System.out.println("onpost" + result);
listener.result(result);
listener.loader(true);
super.onPostExecute(result);
}
public String getMethod() {
return Method;
}
public void setMethod(String method) {
Method = method;
}
public List<NameValuePair> getParams() {
return params;
}
public void setParams(List<NameValuePair> params) {
this.params = params;
}
}
Example

Start function inside overriden Asynctask method of the same class

I have AsyncTask class and I call it in my main class. I need to override the onPostExecute function and call inside ftpDisconnect(). But it does not work properly.
TempClass dj = new TempClass(serialnum) {
#Override
protected void onProgressUpdate(Integer... values) {
pr_bar.setProgress(values[0]);
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(String result) {
//dj.ftpDisconnect(); //need to make this happen
super.onPostExecute(result);
}
};
dj.execute();
My TempClass:
public class TempClass extends AsyncTask<String, Integer, String> {
public TempClass(String serialnum) {
this.serialnum = serialnum;
}
#Override
protected String doInBackground(String... params) {
//do stuff
return null;
}
public boolean ftpDisconnect() {
try {
mFTPClient.disconnect();
return true;
} catch (Exception e) {
}
return false;
}
}
You can't access that instance of dj without making it final. You should be able to call ftpDisconnect from inside the class:
#Override
protected void onPostExecute(String result) {
ftpDisconnect();
super.onPostExecute(result);
}

Categories

Resources