I have a class that is used for various ASyncTasks. Sometimes, I need to hide certain buttons, or views or whatever based upon the Activity or action. The object needing visibility set can vary.
MyAsyncTask
public class MyAsyncTask extends AsyncTask<String, Void, JSONObject> {
private ProgressBar mProgressBar;
public ASynceResponse delegate = null;
public MyAsyncTask() {
this.delegate = delegate;
this.mProgressBar = progressBar;
}
#Override
protected void onPreExecute() {
mProgressBar.setVisibility(View.VISIBLE);
}
#Override
protected JSONObject doInBackground(String... params) {
return;
}
#Override
protected void onPostExecute(JSONObject data) {
mProgressBar.setVisibility(View.GONE);
delegate.processResults(data);
}
public interface ASyncResponse {
void processResults(JSONObject data);
}
}
I usually call it by:
new MyAsyncTask(this, mProgressBar).execute("Something","Something Else",null);
Which I pass in a ProgressBar in the Activity that shows the background action is happening.
But I want more. I want to Overide my classes onPreExecute and onPostExecute to hide/show other items too.
Is that possible?
But I am trying to find a way to Overide the onPreExecute to hide anytype (or many types) views.
Is something like this possible?
MyAsyncTask myAsyncTask = new MyAsyncTask(new onPreExecute(
// hide a view
));
You can do that using interface.
public class MyAsyncTask extends AsyncTask<String, Void, JSONObject> {
private ProgressBar mProgressBar;
public ASynceResponse delegate = null;
public MyAsyncTask() {
this.delegate = delegate;
this.mProgressBar = progressBar;
}
#Override
protected void onPreExecute() {
delegate.myOnPreExecute();
mProgressBar.setVisibility(View.VISIBLE);
}
#Override
protected JSONObject doInBackground(String... params) {
return;
}
#Override
protected void onPostExecute(JSONObject data) {
mProgressBar.setVisibility(View.GONE);
delegate.processResults(data);
}
public interface ASyncResponse {
void processResults(JSONObject data);
void myOnPreExecute();
}
}
Demo class example
class Demo implements ASyncResponse{
.....
void processResults(JSONObject data){
....
}
void myOnPreExecute(){
// do your stuff for pre execute
}
}
Related
I'm trying to do the simple act of hiding/showing ProgressBar according to AsyncTask state ,
I have two classes one extends FragmentActivity and second AsyncTask.
MainActivity.java
public class MainActivity extends FragmentActivity {
public static ProgressBar mProgressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
}
#Override
protected void onStart() {
super.onStart();
// What will happen to the progress bar here?
}
#Override
protected void onStop() {
super.onStop();
// What will happen to the progress bar here?
}
#Override
protected void onResume() {
super.onResume();
// What will happen to the progress bar here?
}
}
MyAsyncTask.java
public class MyAsyncTask extends AsyncTask<Void,Void, Void> {
#Override
protected Void doInBackground() {
// start download some images from cloud
// Here the progress bar should start to appear in MainActivity
// mProgressBar.setVisibility(View.VISIBLE);
}
#Override
protected void onPostExecute(Void result) {
Log.d(TAG, "Finished book downloading images the cloud");
// Here the progress bar should start to disappear in MainActivity
// mProgressBar.setVisibility(View.GONE);
}
}
main_activity.xml
<ProgressBar
android:id="#+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:indeterminate="true" />
Hope you understand me, thank to everyone who can help.
The progress bar should appear in onPreExecute() method (still in UI thread). Then you dismiss it when you get back to UI thread in onPostExecute method.
public class MyAsyncTask extends AsyncTask<Void,Void, Void> {
#Override
protected void onPreExecute(Void result) {
Log.d(TAG, "Finished book downloading images the cloud");
// Here the progress bar should start to disappear in MainActivity
mProgressBar.setVisibility(View.VISIBLE);
}
#Override
protected Void doInBackground() {
// start download some images from cloud
// there is a time cost operation
}
#Override
protected void onPostExecute(Void result) {
Log.d(TAG, "Finished book downloading images the cloud");
// Here the progress bar should start to disappear in MainActivity
// mProgressBar.setVisibility(View.GONE);
}
}
You should use onPreExecute() method to show the dialog.
Here is MainActivity
#Override
protected void onResume() {
super.onResume();
new MyAsyncTask().execute();
}
I think you should read APIs first.
Use preExecute and postExecute methods as they run on UI thread.
public class MyAsyncTask extends AsyncTask<Void,Void, Void> {
ProgressBar pBar;
#Override
protected void onPreExecute(Void result) {
pBar=new ProgressBar(getContext());
pBar.show();
}
#Override
protected void onPostExecute(Void result) {
if(pBar !=null and pBar.isShowing()){
pBar.dismiss();
}
}
}
Use interface in Asyntask class for communicate with Activity class
public class MyAsyncTask extends AsyncTask<Void,Void,Void> {
//use context for activity reference
private Context context_;
public MyAsyncTask(Context context) {
this.context_=context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... voids) {
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if(mCallBack!=null ){
mCallBack.onSuccess("Success");
}else {
mCallBack.onError("Error");
}
}
MyAsyncCallBack mCallBack=null;
public MyAsyncCallBack getmCallBack() {
return mCallBack;
}
public void setmCallBack(MyAsyncCallBack mCallBack) {
this.mCallBack = mCallBack;
}
public interface MyAsyncCallBack{
public void onSuccess(String successMessage);
public void onError(String successMessage);
}
}
Call AsynckTask Class from activity class.Before calling asyntask start progress. and after completing work in asyntask return activity via interface and hide progress.
startProgress();
MyAsyncTask mTask=new MyAsyncTask(YourActivity.this);
mTask.setmCallBack(new MyAsyncTask.MyAsyncCallBack() {
#Override
public void onSuccess(String successMessage) {
//do success work and hide progress
hideProgress();
}
#Override
public void onError(String successMessage) {
//do error work and hide progress
hideProgress();
}
});
mTask.execute();
I want to generate a TextView inside AsyncTask's onPostExecute like this :
protected class AsyncTranslator extends AsyncTask<String, JSONObject, String>
{
#Override
protected String doInBackground(String... params) {
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String mymeaning) {
TextView myView = new TextView(this);
myView.setText(Html.fromHtml(myString));
}
}
But it gives error telling me that this cannot be applied to AsyncTranslator.
Can you tell me how I can generate textViews inside AsyncTask onPostExecute? Thanks.
From the documentation the possible constructors are
TextView(Context context)
TextView(Context context, AttributeSet attrs)
TextView(Context context, AttributeSet attrs, int defStyleAttr)
TextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
but you are doing
TextView myView = new TextView(this);
inside AsyncTranslator which is incorrect.
You can easily create a TextView inside your AsyncTask if you have a reference to your context. See this thread to get a reference to your context.
EDIT
It seems that you already have a reference to your context, so just do
TextView myView = new TextView(context);
In AsyncTask you shouldn't make operations on base UI thread and here you are trying to do it. Try to create new Interface which lets you to pass the result.
public interface asyncTaskInterface {
public void printEditText();
}
Then in your AsyncTask:
protected class AsyncTranslator extends AsyncTask<String, JSONObject, String>
{
public asyncTaskInterface delegate;
#Override
protected String doInBackground(String... params) {
}
#Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(context, "Please wait.", Toast.LENGTH_SHORT).show();
}
#Override
protected void onPostExecute(String mymeaning) {
delegate.printEditText();
}
}
In your result class you have to implement the interface and pass the class to your async task as delegate:
public class myClassActivity implements asyncTaskInterface ...
before you will call async task assign the delegate:
AsyncTranslator translator = new AsyncTranslator();
translator.delegate = this;
translator.execute();
At the end in your activity overwrite the method from your intrface and build in it the TextView.
First create an interface like this:
public interface onTextViewCreatedListener {
public void onTextViewCreated(TextView tv);
}
Then change your AsyncTranslator class like this
protected class AsyncTranslator extends AsyncTask<String, JSONObject, String>
{
private onTextViewCreatedListener onTextViewCreatedListener;
public AsyncTranslator(onTextViewCreatedListener onTextViewCreatedListener){
this.onTextViewCreatedListener = onTextViewCreatedListener;
}
#Override
protected String doInBackground(String... params) {
}
#Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(context, "Please wait.", Toast.LENGTH_SHORT).show();
}
#Override
protected void onPostExecute(String mymeaning) {
//since you have passed context to Toast in onPreExecute use that context here also.
TextView myView = new TextView(context);
myView.setText(Html.fromHtml(myString));
if(onTextViewCreatedListener!=null){
onTextViewCreatedListener.onTextViewCreated(myView);
}
}
}
and then use AsyncTranslator class in your activity class like this:
AsyncTranslator asyncTranslator = new AsyncTranslator(new onTextViewCreatedListener() {
#Override
public void onTextViewCreated(TextView tv) {
//you can use your created textview here
}
});
that context should be passed from your activity where you are going to call aynctask.execute()
I'm trying to get a response back from my public class saveData extends AsyncTask.
I added a public interface but the Android Studio gives me an error for the #Overide on my onCreate in the activity.
public class almostFinish extends Activity implements OnTaskCompleted{
#Override // here I get an Error
protected void onCreate(Bundle savedInstanceState) {}
#Override
public void onTaskCompleted(boolean result) {
//ToDo
}
}
My interface.
public interface OnTaskCompleted {
void onTaskCompleted(boolean isSuccess);
}
My AsyncTask class
public class saveData extends AsyncTask<List<String>, Void, Void> {
private OnTaskCompleted listener;
boolean myflag = false;
#Override
public void onPreExecute() {}
#Override
protected Void doInBackground(List<String>... params) { }
#Override
public void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
listener.onTaskCompleted(myflag);
}
}
Thanks for any help.
I'm just getting an Error in the editor: "Annotations are not allowed here"
If I remove the #Override then I get an Error telling me to add #Override.
According this code you will get null pointer exception. because you have not assign the listener in code.
public class saveData extends AsyncTask < List < String > , Void, Void > {
private OnTaskCompleted listener;
boolean myflag = false;
#Override
public void onPreExecute() {}
#Override
protected Void doInBackground(List < String > ...params) {}
#Override
public void onPostExecute(Void result) {
super.onPostExecute(result);
onTaskCompleted(myflag);
}
}
Learning what I can from the internet and youtube, I'm sure I am not handling this in the appropriate way. I have an existing app which includes a slide out navigation drawer using fragments. I am now trying to get an activity to run within that fragment without any luck. It works when ran on it's own, but after trying to combine the two, I am not able to get "draftactivity" to run properly. The fragment operates as it should.
public class tapsfragment extends Fragment {
public static tapsfragment newInstance() {
tapsfragment fragment = new tapsfragment();
return fragment;
}
public tapsfragment(){}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((MainActivity) activity).onSectionAttached(2);
}
public class DraftActivity extends Activity {
TextView draftfeed;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.draft_activity);
draftfeed = (TextView) findViewById(R.id.draftfeed);
new PostAsync().execute();
}
class PostAsync extends AsyncTask<Void, Void, Void> {
ProgressDialog pd;
XMLHelper helper;
#Override
protected void onPreExecute() {
pd = ProgressDialog.show(DraftActivity.this, "Taps", "Loading posts for ******.com ...", true, false);
}
#Override
protected Void doInBackground(Void... arg0) {
helper = new XMLHelper();
helper.get();
return null;
}
#Override
protected void onPostExecute(Void result) {
StringBuilder builder = new StringBuilder();
for (ItemValue post : helper.posts) {
builder.append("\nPost: " + post.getTitle());
builder.append("\n");
}
draftfeed.setText(builder.toString());
pd.dismiss();
}
}
Activity can't run in a fragment, it's the other way around.
public class AycanClass extends AsyncTask<String, Void, String> implements IAppointments {
Activity activity;
public AycanClass(Activity activity){
this.activity = activity;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
activity.setFilters(value);
}
}
Now in my MainActivity class i have method like this.
public void setFilters(String result){
}
I am not able to call this method.
The method setFilters(result) is undefined for the type Activity
You should use an interface with a single method : here "setFilters"
Your activity should implements this interface and your asynctask constructor will ask for an instance of your interface.
public interface ISetFiltersInterface{
public void setFilters(List<Filter>);
}
public class MyActivity extends Activity implements ISetFiltersInterface{
...
public void setFilters(List<Filter>){
//TODO
}
}
public class AycanClass extends AsyncTask<String, Void, String> implements IAppointments {
ISetFiltersInterface delegate;
public AycanClass(ISetFiltersInterface delegate){
this.delegate = delegate;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
delegate.setFilters(value);
}
}
Edit: make your activity implement an interface that will contain that method.
public interface FilterableActivity {
public void setFilters(String result);
}
And the activity should look like this:
public class MainActivity extends Activity implements FilterableActivity {
...
public void setFilters(String result){
}
}
And just pass a FilterableActivity as a parameter to the Asynctask.
public AycanClass(FilterableActivity activity){
this.activity = activity;
}
This is because the Activity interface doesn't have a setFilter function defined.
You should define this in a Interface and let your Activity implements this one.
public class AycanClass extends AsyncTask<String, Void, String> implements IAppointments {
Activity activity;
MainActivity mainactivityobjectname;
public AycanClass(Activity activity){
this.activity = activity;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
mainactivityobjectname.setFilters(value);
}
}