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();
}
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.
This is the code that I try to use with ButterKnife but I got the following error when I run the project.
error: cannot find symbol class Activity
error: package Activity does not exist
error: package Activity does not exist
BaseActivity
public abstract class BaseActivity extends AppCompatActivity {
private Unbinder unbinder;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutResource());
ButterKnife.bind(this);
setupUI();
}
protected abstract int getLayoutResource();
protected abstract void setupUI();
}
MainActivity
public class MainActivity extends BaseActivity {
#Override
protected void setupUI() {
}
#Override
protected int getLayoutResource() {
return R.layout.activity_main;
}
}
RegisterActivity
public class RegisterActivity extends BaseActivity {
#BindView(R.id.editText_username)
EditText et;
#Override
protected void setupUI() {
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
#Override
protected int getLayoutResource() {
return R.layout.activity_register;
}
#Override
public void onBackPressed() {
this.finish();
}
}
What's my mistake why I can't bind multiple Activities with the abstract class?
Github Project
First, you don't need Unbinder for Activitybecause Unbinder is only needed forFragment`.
Second, you better use another method to be override so that you don't need to set the onCreate. Something like this:
public abstract class BaseActivity extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getLayoutResource());
ButterKnife.bind(this);
setupUI();
}
protected abstract int getLayoutResource();
protected abstract void setupUI();
}
which then you can use:
public class MainActivity extends BaseActivity {
#Override
protected void setupUI() {
// setup the UI.
}
#Override
protected int getLayoutResource() {
return R.layout.activity_main;
}
}
Here is the working example for using ButterKnife with abstract class:
https://github.com/isnotmenow/ButterKnifeAbstractSample
How do I create a method inside onCreate() method? When I am creating its showing error:
Syntax error on token void # expected
And if method can not be created inside onCreate() method than please tell me how do I create a method outside the onCreate() and pass mContext and mActivity from the onCreate() method.
public class MainActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
yourmethod();
}
public void yourmethod(){
// your code here
}
}
public class MainActivity extends Activity {
//Declare a class variable to use in this class
public <data-type> mContext;
public <data-type> mActivity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = <Your value>;
mActivity = <Your value>;
myMethod (mContext , mActivity);
}
private void myMethod (<data-type> mContext, <data-type> mActivity) {
/*
Your Code Goes Here
*/
}
}
*Note that tags like should be replaced by actual types without inequality signs, such as "int" and "short".
I have service, which gets data from API and sends this data to BroadcastReceiver class. Also, I create interface OnReceiveListener, which used in Activity. Look at the code here:
Activity:
public class StartActivity extends AppCompatActivity
implements MyBroadcastReceiver.OnReceiveListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
MyBroadcastReceiver receiver = new MyBroadcastReceiver();
receiver.setOnReceiveListener(this);
LocalBroadcastManager.getInstance(this).registerReceiver(receiver,
new IntentFilter(MyBroadcastReceiver.START));
...
}
#Override
public void onReceive(Intent intent) {
// Do smth here
}
}
MyBroadcastReceiver:
public class MyBroadcastReceiver extends BroadcastReceiver {
public static final String START = "com.example.myapp.START";
public static final String GET_LINKS = "com.example.myapp.GET_LINKS";
private OnReceiveListener onReceiveListener = null;
public interface OnReceiveListener {
void onReceive(Intent intent);
}
public void setOnReceiveListener(Context context) {
this.onReceiveListener = (OnReceiveListener) context;
}
#Override
public void onReceive(Context context, Intent intent) {
if(onReceiveListener != null) {
onReceiveListener.onReceive(intent);
}
}
}
Service isn't important on this question.
---- Question ----
So, what's problem: I want to use this receiver in fragment, but when it sets context - I get exception "enable to cast". What I should to do on this case?
Here is my code in fragment:
public class MainFragment extends Fragment
implements MyBroadcastReceiver.OnReceiveListener {
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
MyBroadcastReceiver myBroadcastReceiver = new MyBroadcastReceiver();
myBroadcastReceiver.setOnReceiveListener(getContext());
LocalBroadcastManager.getInstance(getContext()).registerReceiver(myBroadcastReceiver,
new IntentFilter(MyBroadcastReceiver.GET_LINKS));
}
#Override
public void onReceive(Intent intent) {
// Do smth here
}
}
Your MainFragment class implements your OnReceiveListener interface, not its Context as returned by getContext(). Instead of passing a Context object into setOnReceiveListener(), try directly passing an OnReceiveListener instance. Then your fragment and activity can both call setOnReceiveListener(this).
you don't need to dynamically register the receiver. i believe you must have registered it in manifest using <receiver> tag.
this is not required:
LocalBroadcastManager.getInstance(getContext()).registerReceiver(myBroadcastReceiver,
new IntentFilter(MyBroadcastReceiver.GET_LINKS));
and about callback registering listener, instead of using getContext() use MainFragment.this like this:
myBroadcastReceiver.setOnReceiveListener(MainFragment.this);
After searching for hours for the appropriate way to implement such a solution to this problem, I've found a way finally. It is based on RussHWolf's answer. The complete solution with code is below:
In this way, a setListener() method is exposed so that Fragment or Activity can set the listener by sending an instance of IStatusChangeListener.
public class StatusChangeReceiver extends BroadcastReceiver {
private IStatusChangeListener listener;
public void setListener(IStatusChangeListener listener) {
this.listener = listener;
}
#Override
public void onReceive(Context context, Intent intent) {
if (NetworkUtil.isNetworkConnected()) {
listener.onConnected();
} else {
listener.onDisconnected();
}
}
}
This is the interface:
public interface IStatusChangeListener {
void onConnected(String status);
void onDisonnected(String status);
}
Now, it is required to have an instance of IStatusChangeListener interface instead of implementing the IStatusChangeListener interface. And then, pass this instance of IStatusChangeListener to setListener() method.
public class MainFragment extends Fragment { //Not implementing the interface
private IStatusChangeListener listener = new IStatusChangeListener() {
#Override
void onConnected(String status) {
//some log here
}
#Override
void onDisonnected(String status) {
//some log here
}
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
StatusChangeReceiver r = new StatusChangeReceiver();
r.setListener(listener); // pass the IStatusChangeListener instance
LocalBroadcastManager.getInstance(getContext()).registerReceiver(r, new IntentFilter("connectionStatus"));
}
}
Note: Always use LocalBroadcastManager if you register BroadcastReceiver from Fragment.
The child Class extends a parent Class.
The parent Class has some code I don't want to execute in onCreate().
How can I do this?
Parent:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (!child)
{
... more code ...
}
}
}
Child:
public class SingleArticulo extends MainActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_articulo);
... other code ...
}
}
Use the Template Method pattern.
Base class:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.doMoreOnCreate()
}
protected void doMoreOnCreate() {
... more code ...
}
}
Child:
public class SingleArticulo extends MainActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_single_articulo);
... other code ...
}
#Override
protected void doMoreOnCreate() {
}
}