Getting activity context without instantiating it? - android

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?

Related

Different activities use one non-activity class which needs to access the current running activity's instance variables and manipulate them

I have two activities A and B, and a non activity class C.
To use the methods of C, I create an instance c of C from the currently running activity (say A is in the foreground, and A has created C).
Now, I want to use the instance variables of activity A from c. What should I do?
I am trying to use the non activity C class for multiple activities. Please help me! I have researched it a lot, but still couldn't find anything useful about it. :(
You need to add Activity object inside C constructor and initialize it using the this inside activity A or B.
Code:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
C myLocalCInstance = new C(this); //By using this you pass Activity object
}
C class:
public class C{
Activity mActivity;
public C(Activity callingActivity){
mActivity = callingActivity; // Use mActivity to do as you wish
}
}
You can for instance declare methods in class C as static
public class C{
public static void exampleFuntion(){
}
}
and then use from within A or B:
C.exampleFunction();

How to get activity instance from startActivity() or precisely how to call a method in an activity that we create?

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.

Unable to access Activity's method from Android AsyncTask

I have an issue where I need to access a method in my Activity from Android AsyncTask's onPostExecute() method
I have 2 Activities both contain a common method as below:
(1) Activity1 -- > refreshUI()
(2) Activity2 ----> refreshUI()
I got one AsyncTask call GetDataAsyncTask(Activity a ) which takes calling activity as argument
Now from my activity1 I will call new GetDataAsyncTask(Activity1.this).execute.
Same as above from my activity2 I will call new GetDataAsyncTask(Activity2.this).execute.
My AsyncTask is as below :
public class GetDataAsyncTask extends AsyncTask<String ,Void , String> {
public Activity context;
public PostAsyncTaskHelper(Activity c) {
context = c;
}
protected String doInBackground(String... arg0) {
// Webservice calls
}
protected void onPostExecute(String result) {
if(result.equals("qq")) {
//Where I am not able to access refreshUI()
//method of any one of my activities
context.refreshUI()
}
}
}
Can anyone help me how to get reference of any of the called activities from AsyncTask?
Make an interface that has the method refreshUI(), and make both Activity1 and Activity2 implement it. Then, you just need to typecast context to the type of the interface.
Also, you need to be careful about holding a reference to an Activity from inside an AsyncTask, because in the case of a config change (like screen rotation), you'll be holding on to a destroyed Activity instance. See here for details, and the corresponding example solution to this.
Define an interface for your Activities
public interface MyActivityRefreshInterface
{
public void refreshUI();
}
your Activities must be defined as implements MyActivityRefreshInterface.
Your onPostExecute can then cast the context as (MyActivityRefreshInterface)context
Because refreshUI is not a method in Activity. It is in your particular Acivity1 and Activity 2 classes, not the Activity class from Android. You should refactor so Activity1 and Activity2 to inherit from BaseActivity that has the refreshUI method on it and mark context in the AsyncTask as a BaseActivity

Remove an activity from the stack

I have three activities ActivityA, ActivityB, ActivityC.
Suppose in ActivityA, there is some code like...
if(someCondition()){
gotoActivityB();
}
else{
gotoActivityC();
}
Now, If user goes to ActivityB, ActivityA should not be finished.
If he goes to ActivityC, it should be finished.
Adding noHistory in manifest file doesn't work.
Also, finish()in if condition doesn't work, As there are many activities after ActivityC in which ActivityA should be in background.
I don't want to call startActivity(context,ActivityA.class)in those activities onBackPressed() because, it will again execute code of onCreate() in ActivityA.
So, is there a way, where i can remove ActivityA from the stack when user presses back button in ActivityB?
may be something like this:?
ActivityB.this.finish();
ActivityA.finish(); //some code to finish ActivityA
Okay, here is one way you can accomplish your goal. You will need to pass around the Activity context to wherever you need it in order to call finish() on it. I used the Application class to do this. I only used two classes to do it for the sake of time, but it should work just fine for your purposes. Here is how I did it:
This is the first class. It is the Activity that we want to close from another Activity.
public class MainActivity extends Activity implements OnClickListener {
private Button button;
// application instance
private MainApplication mainApplication;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainApplication = (MainApplication) getApplicationContext();
// set the Activity's context for later usage. Doing this determines which
// Activity can be closed from another Activity.
mainApplication.setActivityContext(this);
button = (Button) findViewById(R.id.button1);
button.setOnClickListener(this);
}
public void onClick(View v) {
switch (v.getId()) {
case R.id.button1:
Intent i = new Intent(this, SecondActivity.class);
startActivity(i);
break;
}
}
}
This is the Second Activity. Exiting out of it will also cause finish() to be called on the first class:
public class SecondActivity extends Activity {
private Activity activityContext;
private MainApplication mainApplication;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_activity_layout);
mainApplication = (MainApplication) getApplicationContext();
// get the Activity context you stored in the MainApplication class
// so you can call finish on it.
activityContext = mainApplication.getActivityContext();
}
#Override
protected void onPause() {
super.onPause();
// closes your defined Activity. If you press the back button you will find
// that you exit right out of the app as the other Activity gets popped off
// the stack.
activityContext.finish();
}
}
And the Application class:
public class MainApplication extends Application {
private Activity activityContext;
public Activity getActivityContext() {
return activityContext;
}
public void setActivityContext(Activity activityContext) {
this.activityContext = activityContext;
}
}
And of course make sure to declare your MainApplication class in the AndroidManifest:
<application
android:name=".MainApplication"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
This is a sort of hacky way to do this. There may be better ways. But regardless, you have to pass around the context of the Activity that you want to call finish() on. Then you can close it from anywhere.
Hi you can finish your activity in current activity itself based on the condition. or use StartActivityforResult based on the result you can finish your activity.
hope this will help you.
You can try this in another way, like i do.
Create a static instance variable of the activity in the beginning.
private static Activity1 thisAct = null; // Activity1 is name of class
Now initialize this variable in onCreate() method
thisAct = this;
Create a static method which will finish this activity
public static void finishActivity()
{
thisAct.finish();
}
While going to Activity C, clear the FLAG :
Intent cIntent = new Intent(view.getContext(), cActivity.class).setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(cIntent);

Finish Activity() from a separate myJavaClass.java

I have tried almost all the solutions from SO but no success :(.
I have a simple myJavaClass.java with a couple of functions.
One of the functions in myJavaClass : startActivity() starts MyCustomActivity
public startActivity(Context context)
{
Intent intent = new Intent(context, MyCustomActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intent);
}
This launches MyCustomActivity() as expected.
Now I have another function in myJavaClass.java to close/finish MyCustomActivity but it is not able to do so!
I have tried
Making MyCustomActivity SingleTop in manifest and creating the activity via an intent as above
Passing an activity instance to "this" in onCreate() of MyCustomActivity and calling MyCustomActivity.activity.finish() from myJava.class but that doesnt work as well
Please help me. I have been stuck here for hours now. I know the solution is very simple and conceptual but I am a newbie. Just building Java/Android concepts!
EDIT
MyCustomActivity
public Activity activity;
OnCreate()
{
...
this = activity;
}
MyJavaClass
public closeActivity(Context context)
{
Activity customActivity = MyCustomActivity.activity;
customActivity.finish();
}
I think that what you are trying to do is fundamentally bad. For a start, outside of the Activity code, there are no guarantees that the activity still exists - the memory manager may have cleaned it up, the user may have pressed Back etc. Think of Activities as independent entities - you can start them, and you can optionally get a result back when they finish what they're doing, but that's it.
Think about whether you really have to programmatically close the activity from outside it - I'd say this is an unusual design, but there are circumstances where it may be appropriate.
If so, what I think you want is a publish/subscribe system whereby MyCustomActivity can register a listener with MyJavaClass, and then receive a callback whereupon it can 'finish' itself.
public Activity activity implements FinishListener
{
public void onCreate(...)
{
//where does MyJavaClass come from? see in a minute
MyJavaClass myjava = getMyJavaclass();
myJava.addFinishListener( this );
}
public void onFinishCallback()
{
this.finish();
}
}
and
public class MyJavaClass
{
private List<FinishListener> finishListeners = ...;
public void addFinishListener( FinishListener fl )
{
this.finishListeners.add(fl);
}
public closeActivity(Context context)
{
for ( FinishListener fl : finishListeners )
{
fl.onFinishCallback();
}
}
}
and
public interface FinishListener
{
void onFinishCallback();
}
Now the only remaining issue is how to get MyJavaClass from the Activity. That's up to you - you may already know how, you may be able to put it in your Application implementation, it could be a singleton (bad), the listeners could be static (bad) or various other options.
Oh, and don't forget to remove the listener again in the Activity's onDestroy() method!
Just try this....
public closeActivity(Activity _activity)
{
_activity.finish();
}
you can't finish activity from other class until you have the reference of instance of Activity in that class, give the reference in that class and call finish() method to stop the activity.
activity.finish();

Categories

Resources