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);
}
}
Related
I have troubles on calling the method update from MainActivity class in a the MSG0100 non-activity class
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void update(boolean msg100Preselection){
if(msg100Preselection){
mExpandableListViewAdapter.setSelectedChild(-1);
mExpandableListViewAdapter.notifyDataSetChanged();
}
}
}
And this is my class where i want to call the update method of Mainactivity.
public class MSG0100{
boolean msg100Preselection=false;
pulic void onUpdate(){
msg100Preselection=true;
// Want to call my update method here
MainActivity activity= new MainActivity();
activity.update(msg100Preselection); //<-------- Using mainactiviy object crashes my app.
}
}
What you want is impossible as you dont have a pointer to your main activity.
The following statement is invalid.
MainActivity activity= new MainActivity();
You are not allowed to use the new operator to create an activity. That should be done using an intent.
There are several things you could do:
Move your update method in another class
OR
declare your update method as static and use it like this:
MainActivity.update(msg100Preselection);
Try using a callbackListener :-
In your MSG0100 class
public class MSG0100 {
boolean msg100Preselection = false;
private static OnUpdateListener mListener;
public static setListener(OnUpdateListener mListener) {
this.mListener = mListener;
}
public void onUpdate() {
msg100Preselection = true;
if (mListener != null)
mListener.onUpdate(msg100Preselection);
}
public interface OnUpdateListener()
{
void onUpdate ( boolean msg100Preselection);
}
}
In your MainActivity-
public class MainActivity extends AppCompatActivity, OnUpdateListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MSG0100.setListener(this)
}
#Override
public void onUpdate(boolean msg100Preselection) {
if (msg100Preselection) {
mExpandableListViewAdapter.setSelectedChild(-1);
mExpandableListViewAdapter.notifyDataSetChanged();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
MSG0100.setListener(null)
}
}
This way you won't have any memory leaks or crashes due to Activity being killed.
My project have 1 activity class, 1 interface class and 2 classes. One class is extends with AsyncTask.
Activity Class
public class ActivityClass extends AppCompatActivity implements TaskListener {
TaskListener listener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Call asyncTask class
Server myServer = new Server(listener);
myServer.execute(request);
}
#Override
public void taskComplete(boolean status) {
//Task complete
}
}
Interface Class
public interface TaskListener {
public void taskComplete(boolean status);
}
AsyncTask Class
public class Server extends AsyncTask<JSONObject, Void, Void> {
TaskListener listener;
public Server(TaskListener l) {
this.listener = l;
}
#Override
protected Void doInBackground(JSONObject... params) {
...........
}
#Override
protected void onPostExecute(Void result) {
listener.taskComplete(success);
}
}
Other Class
public class Operation extends TaskListener {
}
I've got an error in Other Class (No interface expected here). I'm confused how can I implement Interface class in the both class.
public class Operation extends TaskListener {}
Because extends expects a class, not an interface. Interface should be used with implements. Change to:
public class Operation implements TaskListener {}
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
}
}
I have one activity and 2 fragment.
I want when in activity fire listener.receivePreview(obj) then
execute : OneFragment -> receivePreview .
execute : TwoFragment -> receivePreview .
public class MainAct extends AppCompatActivity {
public interface OnReceiveListener {
// This can be any number of events to be sent to the activity
void receivePreview(Object... obj);
}
private OnReceiveListener listener;
}
public class OneFragment extends Fragment implements OnReceiveListener{
#Override
public void receivePreview(Object... obj) {
}
}
public class TwoFragment extends Fragment implements OnReceiveListener{
#Override
public void receivePreview(Object... obj) {
}
}
I think you can use Observer Pattern that is a good practice in you situation.
As described by GoF:
"Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically".
Read more at http://www.java2blog.com/2013/02/observer-design-pattern-in-java.html#TLio7G2ruqxvfZUR.99
In your situation you have such relation (one-to-many) and when an event occurred in the activity you want to aware that two fragment.
Fragments are implement observer class and your activity has the role of subject as illustrate in above figure.
I hope this could help you to implements your code in a very nice way.
some tutorial can be find in the following links :
https://dzone.com/articles/observer-pattern-java
http://www.tutorialspoint.com/design_pattern/observer_pattern.htm
Edit: in the given situation:
public interface OnReceiveListener { // this is your observer interface !
// This can be any number of events to be sent to the activity
void receivePreview(Object... obj);
}
Fragment are in correct definition with this design pattern so I do not change their code :
public class OneFragment extends Fragment implements OnReceiveListener{
#Override
public void receivePreview(Object... obj) {
}
}
public class TwoFragment extends Fragment implements OnReceiveListener{
#Override
public void receivePreview(Object... obj) {
}
you need to have references to the fragments in the activity (as observer).
ArrayList< OnReceiveListener > observers = new ArrayList< OnReceiveListener>();
indeed an observer can subscribe or register itself to a subject ( fragment hold a reference to the activity (better to use singleton pattern ! :D). like this :
public class MainAct extends AppCompatActivity {
private static MainAct instance;
public static MainAct getInstance() {
if(instance != null)
return instance;
}
// I think it is better to create the instance variable in the onCreate() method of the MainAct activity
onCreate(...)
{
.
.
.
instance = this;
...
}
public void registerObserver(OnReceiveListener observer){
observers.add(observer)
}
/* To avoid memory leaks, remember to unregister receivers when no longer observing */
public void unregisterObserver(OnReceiveListener observer) {
observers.remove(observer);
}
notifyObservers(){
// call this method in the listener you want
for( Observer obser : observers)
obser. receivePreview(param )
}
...
//in fragment initialization:
MainAct.getInstance().registerObserver(this)
I use answer Sirvan Paraste.It seems that this useful solution.
public class MainAct extends AppCompatActivity {
static List<OnReceiveListener> onReceiveList = new ArrayList<OnReceiveListener>();
public void attachOnReceiveListener(OnReceiveListener listener) {
if (!onReceiveList.contains(listener)) {
onReceiveList.add(listener);
}
}
public interface OnReceiveListener {
// This can be any number of events to be sent to the activity
void receivePreview(Object... obj);
}
public onReceivePreview(Object... obj) {
for (OnReceiveListener listener : onReceiveList) {
listener.receivePreview(obj);
}
}
}
public class OneFragment extends Fragment implements OnReceiveListener{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainAct mainAct = new MainAct();
mainAct.attachOnReceiveListener(this);
}
#Override
public void receivePreview(Object... obj) {
}
}
public class TwoFragment extends Fragment implements OnReceiveListener{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainAct mainAct = new MainAct();
mainAct.attachOnReceiveListener(this);
}
#Override
public void receivePreview(Object... obj) {
}
}
Try to create one function in each fragment which returns the interface instance
public OnReceiveListener getListener() {
mListener = this;
return mListener
}
and in your activity when you call the method write following code
fragmentInstance.getListener().receivePreview();
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);
}
}