Suppose I have a class A and contains a method which needs and activity and an int as parameters:
class A {
public void performActions(Activity activity, int a){
.....}
}
Now the following activities are accessing method performActions() in class A:
class B extends Activity{
public void aMethod(){
new class A().performActions(B.this, 1);
}
}
class C extends Activity{
public void aMethod(){
new class A().performActions(C.this, 2);
}
}
The question is:
Is there a way that performActions() method in class A know that the activity parameter came from which activity and get back to that activity when it done its actions?
you can keep a check like this
public void performActions(Activity activity, int a){
if(activity instanceOf B){
//came from B
}
if(activity instanceOf C){
//came from C
}
}
I'm not exactly sure what you are meaning.
However,
I would think that you may want to provide a method that B,C overrides from Activity class, that returns which class it is (B or C).
Otherwise consider adding names to activities through some method in Activity.
You don't provide much information about the use case of this code, so it is difficult to answer.
You can use instanceOf to know that context belong to which activity.
Here is the below code for the same
if (context instanceof ActivityA) {
} else {
if (context instanceof ActivityB) {
}
}
Related
This question already has answers here:
Passing data between a fragment and its container activity
(16 answers)
Closed 5 years ago.
Do not understand fully fragment life-cycle.
Case:
Click FrameLayout from Activity to move to Fragment is working.
Problem:
In Fragment there are two spinners and one SubmitButton, when selected both spinner values, the clicking ofSubmitButton, should display those values from spinner back to the Activity's two Textviews . But, I am unable to do that.
My Solution:
I tried to use Intent, putExtras and then getExtras , but as we are in Fragment, Intent is not going to work for Fragment. Bundle also not helping.
P.S. Need someone who understand good Fragment's life-cycle. Read many posts from stackoverflow and other tutorials. Not found what I meant.
Do not want external libraries as such eventBus
Two ways you can do that
1) Casting getActivity() as your Activity and call the specific method and pass parameter.
public class MyActivity extends AppCompatActivity {
public void setData(String value){
// do whatever with the data
}
}
public class MyFragment extends Fragment{
public void someMethod(){
((MyActivity)getActivity).setData(your_data);
}
}
2) Create an interface and pass the value to activity.
public class MyActivity extends AppCompatActivity implements SpinnerListener{
#Override
public void onSpinnerItemSelected(String value){
// do whatever with the data
}
public interface SpinnerListener {
void onSpinnerItemSelected(String value);
}
}
public class MyFragment extends Fragment {
private SpinnerListener spinnerListener;
#Override
public void onAttach(Context context) {
super.onAttach(context);
if(context instanceOf MyActivity)
spinnerListener = ((MyActivity)context);
}
public void someMethod() {
if(spinnerListener != null)
spinnerListener.onSpinnerItemSelected(your_data);
}
}
Note: The safe method is using interface.
My project have a activity named MainActivity and a BrowserActivity extend dialog service.
MainActivity will intent BrowserActivity on application started.
I would like to BrowserActivity can access MainActivity's public method.
something like that:
Method on MainActivity:
public void chooseShare(Intent intent)
{
try
{
startActivityForResult( intent , PICK_SHARE);
} catch (android.content.ActivityNotFoundException ex)
{
Log.e("Share" , ex.getMessage());
}
}
And i want to do on BrowserActivity :
(Pseudocode)
((MainActivity)BrowserActivity.this.getOwnerActivity()).chooseShare(intent);
I try to do that:
MainActivity ma = new MainActivity();
ma.chooseShare(i);
However, it not work, it throw NULLPointerException.
Because i need startActivityForResult() instead of startActivity() for callback result.
And i digg on SOF, i found startActivityForResult() should be start on Activity, but not Dialog.
thanks you.
You should be able to use getParent() if it's within the same project.
Activity parent = getParent();
if (parent instanceof MainActivity)
((MainActivity)parent).chooseShare(i);
Another option would be to bind it with an ibinder and use a service or implement interfaces.
Services | Android Developers
you can access all classes method like this:
Context context;
public ProceedDialog(#NonNull Context context) {
super(context);
this.context = context;
//do something
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//do something
}
#Override
public void onClick(View view) {
ParentActivity activity = (ParentActivity)context;
activity.method();
}
I had the same question. And I found a partial solution.
The key is that Activity is a subclass of Context.
You pass the Context paraneter to the constructor of your dialog, right?
And most people pass it by using this of MainActivity.
So, I used the following codes to get MainActivity reference.
private MainActivity getMainActivity()
{
Context c= getContext();
if( c instanceof MainActivity)
{
return (MainActivity)c;
}
return null;
}
Then you can call the desired method by
this.getMainActivity().chooseShare(intent);
In the dialog.
I tested this and it works!
Hope it helped you or forecomers.
(I saw the last modification date just now)
Fragment has a method named getActivity() which returns the activity with which the fragment currently is associated.
Is it safe to not use this method, but instead save the Activity instance in the onAttach(Activity) method?
For example, change from:
public class MyFragment extends Fragment {
public void foo() {
((MainActivity) getActivity()).foo();
}
}
to:
public class MyFragment extends Fragment {
private MainActivity activity;
public void onAttach(Activity activity) {
this.activity = (MainActivity) activity;
}
public void foo() {
this.activity.foo();
}
}
Are there any differences between these two approaches? Which is better?
PS. One benefit of the second approach is that you don't have to do type conversion each time you use the activity (like (MainActivity) getActivity()). But I don't know whether it's safe to save the activity instance.
yes it's ok. I do that almost always to avoid calling method getActivity() and casting result every time (for better performance and better code)
Given the code:
public class CommandSequence {
public CommandSequence() {
}
public void startCommunications(View v) {
Bundle dataout1 = new Bundle();
dataout1.putInt("ACTION", Communications.ACTION_LOAD_COMMAND_ONLY);
dataout1.putInt("PORT", Commands.MESSAGE_TYPE_SMC);
dataout1.putInt("COMMAND", Commands.SMC_RESETEVENTSTATUS);
((MainActivity) v.getContext()).sendMessageToBackgroundCommunicationsService(
Communications.MESSAGE_LOAD_COMMAND,
dataout1);
}
}
I must cast 'sendMessageToBackgroundCommunicationsService()' with the calling activity context, which is 'MainActivity'.
Is it possible to pass a parameter that will allow me to cast the method call at runtime, so that this method can be called from any activity class?
Why not create a base activity class that all your activies inherit and then cast to this instead when you need to make a call:
((MyBaseActivity) v.getContext()).sendMessageToBackgroundCommunicationsService(
Communications.MESSAGE_LOAD_COMMAND,
dataout1);
[EDIT] In fact to make your code a bit better you could pass the activity into your method so there is no dependency on your class needing to know another class.
public void startCommunications(View v, Class myActivity) {
//your code
}
I am currently working on an android project and I have an activity, lets call it MyActivity and this activity calls a standard Java class called MyClass.
I need MyClass to finish the MyActivity activity but I can't find out how to do this. I thought I might be able to pass the context to the standard java class and call context.finish() but this doesn't appear to be available.
How can I do this, thanks for any help you can offer.
You can pass the Context, but you will need to cast it to an Activity (or simply pass the Activity itself), although this in general seems like a bad practice.
The most secure solution uses listener and a Handler. It is complex, but ensures a non direct call to finish activity.
Your listener:
interface OnWantToCloseListener{
public void onWantToClose();
}
Class that should close activity.
class MyClass {
private OnWantToCloseListener listener;
public void setWantToCloseListener(OnWantToCloseListener listener){
this.listener = listener;
}
private void fireOnWantToClose(){
if(this.listener != null)
listener.onWantToClose();
}
}
When you want to close your activity you must call fireOnWantToClose() method.
public MyActivity extends Activity{
public void onCreate(){
final int CLOSE = 1; //number to identify what happens
MyClass my_class = new MyClass();
final Handler handler = new Handler(){
public void handleMessage(Message msg){
if(msg.what == CLOSE)
MyActivity.this.finish();
}
});
my_class.setOnWantToCloseListener(new OnWantToCloseListener(){
public void onWantToClose(){
handler.sendEmptyMessage(CLOSE);
}
});
}
}
This is secure because Activity is not finished directly by MyClass object, it is finished through a listener that orders a handler to finish activity. Even if you run MyClass object on a second thread this code will works nice.
EDIT: CLOSE var added I forget to declare and initialize this.
Pass the MyActivity to MyClass as an Activity. From there you can call myActivity.finish();
For example:
private Activity myActivity;
public MyClass(Activity myActivity){
this.myActivity = myActivity;
}
public void stopMyActivity(){
myActivity.finish();
}
And in MyActivity:
MyClass myClass = new MyClass(this);
This is risky, because you're holding a reference to an Activity, which can cause memory leaks.
If your java class is a nested inner class, you can use:
public class MyActivity extends Activity {
public static class JavaClass {
public void finishActivity() {
MyActivity.finish();
}
}
}
Otherwise you'll have to pass the java class a Context (i.e. pass it a reference to this, since Activity extends Context) and store it as a private instance variable.