I have a base activity containing action bar. I have options like: share, refresh in the action bar. But those methods are written in the fragments and have the instance of the fragments in another activity which is extending the base activity. So how to get the instance of the activity containing fragments?
In your SubActivity, define a member:
private SubActivity instance = this;
and also define a method:
public static Activity getSubActivityInstance(){
return instance;
}
In your BaseActivity, you can then use:
SubActivity mySubActivity = SubActivity.getSubActivityInstance();
if(mySubActivity != null){
// now call methods defined in SubActivity class
}
This will only work after an instance of SubActivity has been created (obviously), not before.
Related
I have two activities (A and B). Activity A calls activity B. Activity B has Back (Up) button like this:
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Now when this UP button is pressed, onCreate of activity A is again called. In the activity A, there is a classId variable (which I got from an Intent) which I want to retain. For this I have following code in my onCreate of activity A:
if (savedInstanceState == null)
{
Intent intent = getIntent();
classId = intent.getIntExtra("CLASS_ID", 0);
}
else
{
classId = savedInstanceState.getInt("CLASS_ID");
}
I have also overriden the onSavedInstanceState method:
#Override
protected void onSaveInstanceState(Bundle savedInstanceState)
{
savedInstanceState.putInt("CLASS_ID", classId);
super.onSaveInstanceState(savedInstanceState);
}
I am following this SO answer:
onCreate being called on Activity A in up navigation
The problem I am facing is that when I come again to activity A by passing back button in activity B, onCreate gets called and I found savedInstanceState to be NULL.
Edit:
Is there any other way to save my classId variable so that when I return again to activity A, I can use that?
Edit 2
If I set launch mode of my activity A to SingleTop in the manifest file, my issue gets resolved. Is it the right approach?
You should not suppose that onSaveInstanceState called each time you go to next activity.See the docs
This method is called before an activity may be killed so that when it comes back some time in the future it can restore its state. For example, if activity B is launched in front of activity A, and at some point activity A is killed to reclaim resources, activity A will have a chance to save the current state of its user interface via this method so that when the user returns to activity A, the state of the user interface can be restored via onCreate(Bundle) or onRestoreInstanceState(Bundle).
You may further consult with official docs here
Try this
public class SingletonHolder {
//your id here as what data type you want
private static SingletonHolder instance;
public static SingletonHolder getInstance() {
if (instance == null) {
instance = new SingletonHolder();
}
return instance;
}
//set getter setter here
}
If not successfull feel free to comment
I changed the launchMode of the activity A to singleTop in the mainfest file like this:
android:launchMode="singleTop"
I followed this question on SO: Setting launchMode="singleTask" vs setting activity launchMode="singleTop"
By using this approach, activity A is not destroyed and when I just finish the activity B or click UP navigation in activity B, the existing instance of activity A is launched again.
I have been struggling with this problem for two days,I am in situation where i need to use a method in ActivityB from ActivityA . The problems lays in getting the context of A i have tried many solutions like:
static ActivityA activityA;
In onCreate state:
activityA = this;
and add this method:
public static ActivityA getInstance(){
return activityA;
}
In ActivityB, call
ActivityA.getInstance().myFunction(); //call myFunction using activityA
it did not work out because this need the ActivityA to be instantiated in order to pass its context to A but this is not accomplishable in my case is there any way of getting an activity's context without switching activities .
my question might turn out to be simple or intuitive but im new to this concept , thanks in advance
As you want to have common functionality in both activities, you can create BaseActivity that extends Activity and define your method in that and extend ActivityA and ActivityB by BaseActivity then you can access methods.
You can do it like this,
public class BaseActivity extends Activity
{
public void myFunction()
{
...
}
}
And do this for other activities:
public class ActivityA extends BaseActivity
{
public void someMethod()
{
myFunction(); // you can call function here directly
}
}
You could extent class A using Class B simply
OR
public static ActivityA activityA;
In onCreate state:
{
activityA = this;
}
Outside Oncreate
public myFunction{
}
and in ActivityB call
activityA.myFunction();
Here I Created Two Classes Consider as Activities , And Then Created one Public methodA() in class Activity_A , then Created Class Activity_B and Created methodB() , And Created Object of Activity_A and Called methodA() by passing context of Activity Activity_B .
class Activity_A{
public void methodA(Context context){
Toast.makeText(context,"methodA",Toast.LENGTH_LONG).show();
}
}
class Activity_B{
public void methodB(){
Activity_A activity_a = new Activity_A();
activity_a.methodA(Activity_B.this);
}
}
There are two options:
1) Add the static keyword to your shared methods
OR
2) You can try reflection.
For reference follow the link:
What is reflection and why is it useful?
Im trying to figure a way how to call an activity that an adapter has started. Is there a way to get the instance of the activity from startactivity and make a method call into the activity ?
I'ved got an adapter that has a list
public class LanguageDownloadRVAdapter extends RecyclerView.Adapter<LanguageDownloadRVAdapter.DownloadViewHolder>{
And in this adapter, it starts a particular activity called MainActivity
context.startActivity(new Intent(context, MainActivity.class));
((Activity)context).finish();
Here is the MainActivity that it starts
public class MainActivity extends AppCompatActivity implements IabBroadcastListener{
How can I make a call from the adapter to a method in the MainActivity. (im just trying to perform inapp purchase which is implemented in the MainActivity). so how can i do something like this.
mainactivity.perform_inapp_purchase();
Try to use EventBus for passing data between activity and list adapter. You can do it in the same way for passing data between activity and fragment.
This work the same way as storing data in global variable (in a fancier way)
In the adapter:
Add a new Field private Context mContext;
In the adapter Constructor add one more parameter as below, and assign it into class level variable:
public LanguageDownloadRVAdapter(......,Context context){
//your code.
this.mContext=context;
}
In the Adapter where you want to call Activity's perform_inapp_purchase() method:
if(mContext instanceof MainActivity){
((MainActivity) mContext).perform_inapp_purchase();
}
More Generalized Approach:
If you need to use this same adapter for more than one activity then :
Create an Interface
public interface InAppPerchaceInterface{
void perform_inapp_purchase();
}
Implement this interface in activities
Then in Adapter, call like below:
if(mContext instanceof InAppPerchaceInterface){
((InAppPerchaceInterface) mContext).perform_inapp_purchase();
}
You can store the instance in the application class, but you should be careful about the memory leaks.
In the onCreate of your activity
protected void onCreate(Bundle savedInstanceState)
{
// get the instance using this and store it in the application class or in the place that you want to call from it
}
From where will you call your method?
I didn't understand the situation.
How can I manipulate another Activity's XML file components (like EditText) from main Activity, in terms of setEnabled() etc. Do I need to instantiate a field MySecondActivity inside MainActivity class and manipulate it via methods i create in that second Activity?
I tried without doing that. I instantiated EditText editText = findViewById(R.id.edit_text) in onCreate() method at Main Activity which is contained in the second Activity's xml, but that gives me null pointer exception.
By android design, each Activity like different application, have to work independed as it can. You should send parameters as extras in intent and do your work it that activity.
But you can do it, for example linking activities by static field:
ActivityA {
public static ActivityB instance = null;
onClick() {
startActivity(new Intent(this, ActivityB.class));
}
}
ActivityB {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityA.instance = this;
}
}
After that you can access AcitivityB from ActivityA by "instalce", but again, this is not the right way!
This is unlikely but it would potentially save me a lot of time to re-write the same code.
I want to implement a UI using alert-type service (like Chathead) yet I'd still like to use my fragments. Is it possible? I know I can add views to the window but fragments?
Fragments are part of the activity, so they cannot replace activity. Though they behave like activity, they cannot stand themselves. Its like view cannot itself act like activity.
From Android Developers:
A Fragment represents a behavior or a portion of user interface in an
Activity. You can combine multiple fragments in a single activity to
build a multi-pane UI and reuse a fragment in multiple activities. You
can think of a fragment as a modular section of an activity, which has
its own lifecycle, receives its own input events, and which you can
add or remove while the activity is running (sort of like a "sub
activity" that you can reuse in different activities).
I hope it is helpful to you.
Well as people have pointed out you can't, but, you can always create
some sort of fragment wrapper.
For example purposes:
public class ActivityFragmentWrapper extends FragmentActivity {
public static final String KEY_FRAGMENT_CLASS = "keyFragmentClass";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getIntent().getExtras() != null) {
String fragmentClass = (String) getIntent().getExtras().get(KEY_FRAGMENT_CLASS);
try {
Class<?> cls = Class.forName(fragmentClass);
Constructor<?> constructor = cls.getConstructor();
Fragment fragment = (Fragment) constructor.newInstance();
// do some managing or add fragment to activity
getFragmentManager().beginTransaction().add(fragment, "bla").commit();
} catch (Exception LetsHopeWeCanIgnoreThis) {
}
}
}
public static void startActivityWithFragment(Context context, String classPathName) {
Intent intent = new Intent(context, ActivityFragmentWrapper.class);
intent.putExtra(KEY_FRAGMENT_CLASS, classPathName);
context.startActivity(intent);
}
}
You can start it like:
ActivityFragmentWrapper.startActivityWithFragment(context, SomeSpecificFragment.class.getCanonicalName().toString());
Of course if your fragment has another constructor you have to retrieve different
one, but that part gets easier.
No, Fragments can't exist without an Activity. They need an activity for their entry point otherwise they can't initiate their UI components and their lifecycle can't go beyond onAttach and onCreateView