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 {}
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.
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);
}
}
I have an interface MyListner
public interface MyListner{
public void onOperationComplete();
}
I have two Activity SignIn and SignUp which implements MyListner
public class SignIn extends Activity implements MyListner{
#Override
public void onOperationComplete(){
Log.e("SignIn","Operation Complete");
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Operation.doOperation();
}
}
public class SignUp extends Activity implements MyListner{
#Override
public void onOperationComplete(){
Log.e("SignUp","Operation Complete");
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Operation.doOperation();
}
}
Inside onCreate() of both Activity i am calling a static function doOperation() inside the class Operation for doing some operation by Operation.doOperation().
public class Operation{
publis static void doOperation(){
...........
...........
...........
//here i want a callback to interface funtion onOperationComplete()
}
}
My requirement is that i want to get a callback to the function onOperationComplete() inside all the class which implements MyListner
make your doOperation like this:
public class Operation{
publis static void doOperation(MyListener callBack){
...........
...........
...........
//here i want a callback to interface funtion onOperationComplete()
callBack.onOperationComplete();
}
}
In Your Activity:
public class SignIn extends Activity implements MyListner{
#Override
public void onOperationComplete(){
Log.e("SignIn","Operation Complete");
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Operation.doOperation(this);
}
}
You may want to look for Observer pattern
You can make your Operation class singleton
Add an attribute of "Collection listeners" inside Operation class
Add a public method called "addListener(MyListener)" which stores the passed parameter into the "listeners" attribute
Inside onCreate() of the Activity, call
Operation.getInstance().addListener(this);
When you want to perform the operation, call
for(MyListener listener : listeners){
listener.onOperationComplete();
}
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);
}
}