Static Context from Activity.onStart() - java

I am trying to generate a notification from a class, Utilities.java, outside of the subclass of Context. I've thought about providing a SingletonContext class and have looked at posts ike this. I'd like to be able to return != null Context object since the notification can be generated at any given time because it is generated from a messageReceived() callback.
What are there downsides to doing something like this:
public static Context c;
public class MainActivity extends Activity{
#Override
public void onStart()
super.onStart()
c = this.getApplicationContext();
}
//other method somewhere outside this class
public Context getContext(){
return MainActivity.c
}
I don't think it would be any different than putting this on the onCreate(), however, it guarantees that the context is up to date when the activity starts.

The Context keeps a reference to this activity in memory, which you might not want. Perhaps use
this.getApplicationContext();
instead. This will still let you do file IO and most other things a context requires. Without a specific reference to this activity.

Maybe you should overwrite the onResume Method.
If you open a new activity, and switch back, the onStart method will not getting invoked.
Android Lifecycle: doc
BTW: I read about problems with ApplicationContext using a dialog or toast, so if you use the context to create on of these you should use your Activity as context.

Related

Android - Hold Activity reference in application-level non-Activity class

I have an application class and it holds a reference of MyAdapter class:
public class MyApplication extends Application {
......
private static MyAdapter sMyAdapter;
public static MyAdapter getMyAdapter() {
if (sMyAdapter == null) {
sMyAdapter = new MyAdapter(this);
MyApplication.setMyAdapter(sMyAdapter);
}
return sMyAdapter;
}
public static void setMyAdapter(MyAdapter myAdapter) {
sMyAdapter = myAdapter;
}
......
}
MyAdapter class is a customized android adapter class, and the application Context is passed to the Adapter. The application holds a reference of it because it may be used anytime till the application is still running.
The problem is that now I need an Activity Context in the Adapter to start another Activity when some button is clicked because if I use application Context I need to add a Intent flag FLAG_ACTIVITY_NEW_TASK which I don't want to because that way the new Activity being started will be running in a new task. I tried a lot with changing launch mode and taskAffinity but either new issues came up or the Activity will be running in a new task.
So I am thinking to hold an Activity reference which shows the button in the Adapter class, and to avoid memory leak, I came up with the following:
public class MyActivity extends Activity {
......
#override
public void onResume() {
......
MyApplication.getMyAdapter().setActivity(this);
......
}
......
#override
public void onDestroy() {
......
MyApplication.getMyAdapter().setActivity(null);
......
}
}
Then in the Adapter class I will use the Activity reference to start another Activity. I tested and this worked fine but the question is would this avoid memory leak and is this a proper way to hold the Activity reference when onResume and release it when onDestroy? Is there any other decent way to achieve my purpose? Thanks.
would this avoid memory leak
Not really. You MyApplication object will still keep a reference to your adapter with all it's 'contents' (further references).
Yes, you've got rid of keeping the destroyed Activity around, and you might feel it's okay to keep the adapter because you're 'going to need it again anyways', still this whole construct is a horrible code smell and will with certainty introduce new memory leaks and other problems as you develop this further.
Logically, this adapter is part of an Activity, and as the Activity 'dies', so should the adapter.
I'm sure there's a reason why you felt you needed that adapter on your application, so I'd post another question asking 'how can I achieve soandso without my application knowing of my adapter'.

Complications while converting an Android application to a library

I had an Android application(MyApp, say) that used ApplicationContext extensively. The ApplicationContext was made available via a class that extended Application.
class MyApp extends Application {
static Context mContext = null;
public void onCreate() {
mContext = getApplicationContext();
}
public static Context getContext() {
return mContext;
}
}
I would like to convert this application to a library and use it in another application ( AnotherApp, say). Now I see that AnotherApp already has a similar class that extends Application and gives its context everywhere within itself. When I move MyApp as a library into AnotherApp, my code will not be able to get ApplicationContext anymore - as only one class can be declared in Manifest (android:name=".AnotherApp")
What is the best way to make application context available within library? I do not mind making extensive code changes, but would like to know options I have - other than passing context to every api in my library.
A library should never use the getApplicationCOntext it is meant for the main program.
you can pass the context using a function or save it into a public static variable in your class in the beginning.
Note about code design
This completely depends on how you want to use the library, will the functions be used in the main app ? Will the activity be directly called ? and a bunch of other code design things like that.
If you want two activities sometimes the best way it to make them into separate applications and make one call the other using an Intent. Like how google maps and other inbuilt services are used.
If you want to use your library's function in the main application, you should not be creating an activity at all. Rather you should make an abstract class that the user can inherit from and use your class through.
I have done similar stuffs in my Application.
Its true you will not able to get context in your library
You will have context of only AnotherApp
If you want to use Context in your library in that case you need to have some method which can pass your AnotherApp's context to your library.
For example
class MyApp extends Application {
static Context mContext = null;
public void onCreate() {
mContext = getApplicationContext();
objecofYourLibClass = new MyApp();
objecofYourLibClass.yourMethod(mContext);
}
}
Now you will able to use context in your Library.

How can I get the context in the finish() method?

I'm just rtying to display an offerwall when someone is leaving the application, so I have placed the finish() method:
#Override
public void finish() {
super.finish();
MobileCore.init(this.getContext(), "xxx", MobileCore.LOG_TYPE.DEBUG, MobileCore.AD_UNITS.OFFERWALL);
MobileCore.setStickeezReadyListener(new OnReadyListener() {
#Override
public void onReady(MobileCore.AD_UNITS adUnit) {
if (adUnit == MobileCore.AD_UNITS.OFERWALL) {
MobileCore.showOferWall(getActivity());
}
}
});
}
But I have problems. First of all with this code this.getContext() and also with this getActivity()
I know that I can not access the activity this way, but I'm extremely confused at the moment. I know that I'm missing a very small part here. Can you give me a push?
Activity class extends Context so actually Activity is instance of Context, in onFinish the system is trying to destroy the Activity so there must be no jobs still working related to this Activity, if you still need a Context you can use this.getApplicationContext.
To call the outer class in a nested class (in your case an anonymous class) use the class name of the outer one:
YourOuterClass.this
Your activity's context will remain valid until you call super.finish(). So don't call it until you're done.
If you can't do that, use the application context.

Inject Context to activity

I am combining a static code analysis with a dynamic one. I basically create a new activity and set it up as the starting activity. During the run various methods in existing activities should be called.
I can call e.g. onCreate from outside, however, the super call to Activity will fail (or calls to SharedPreferences or other interesting classes) since Android does some initialization stuff when using the intents in order to call an activity (e.g. setting the context). But I need to somehow call methods like onCreate or onPause from outside while giving the target activity a valid context.
In my newly created activity I have got a valid context. I tried to pass it via calling ContextWrapper.attachBaseContext, but there is still a NullPointerException somewhere in Android due a the missing context. Is there some way to hack this somehow into a working state? Using reflection or other hacks would be no problem, since it is for analysis purposes only.
Thank you very much for any tips. I'd be able to modify the analyzed apps in any way to get this working.
However: Using an Intent is no option, since I cannot control which Activity-methods are being called, when and how often. I know that android has not been made for calling these methods directly, but it is not a common use case either :);
I have created a hack, which seems to help (I can get a valid context in the hacked activity). Let's see how far I get using this.
public static void hack(Activity hack, Activity main) {
try {
Field mActivityInfo = getField(Activity.class, "mActivityInfo");
mActivityInfo.set(hack, getClass("android.content.pm.ActivityInfo").newInstance());
Field mFragments = getField(Activity.class, "mFragments");
Field mContainer = getField(Activity.class, "mContainer");
Field mApplication = getField(Activity.class, "mApplication");
Field mWindow = getField(Activity.class, "mWindow");
Class FragmentManagerImpl = getClass("android.app.FragmentManagerImpl");
FragmentManager manager = (FragmentManager) mFragments.get(hack);
mApplication.set(hack, main.getApplication());
mWindow.set(hack, main.getWindow());
Class<?> FragmentContainer = getClass("android.app.FragmentContainer");
Method attachActivity = getMethod(FragmentManagerImpl, "attachActivity", Activity.class, FragmentContainer, Fragment.class);
attachActivity.invoke(manager, hack, mContainer.get(hack), null);
Method attachBaseContext = getMethod(ContextWrapper.class, "attachBaseContext", Context.class);
attachBaseContext.invoke(hack, new HackContext(main));
System.out.println("Hack performed");
} catch (Exception e) {
e.printStackTrace();
System.err.println("Hack failed :(");
}
}

Context having reference to class in android

Hi i am trying to understand the use of context though i couldn't. Following is a program using context. My question is what is the significance of " context = class.this " ?
class public VcardActivity extends Activity
{
String Vcard = "vcard";
Context context;
}
public void onCreate ( Bundle bn )
{
super.onCreate(bn);
setContentView(R.layout.main);
context = VcardActivity.this;
}
Your current code doesn't show the use of context. It shows that the Activity is a context.
TextView someText=new TextView(context);
This code of mine shows, I am passing a context into the constructor of a TextView in order to make this object. The reason is, this object needs to know the information, state of the current context, and this is the reason why many views, classes, helpers needs a context.
context = VcardActivity.this;
in your code you are having your activity object to assign to the Context context. This works because Activity class inherits from Context and many classes needs a Context to create it.
In your case, the field context is not necessary at all. It rather is used as a shortcut to VcardActivity.this here. You could remove it without any problems and use VcardActivity.this or even only this where you used to use context.
You don't need to create a separate Context variable inside of an Activity. You use Context for certain objects/methods that need to know what is starting them. Activity already has a Context so you don't need to create it. If you need to use Context within an Activity, say when creating an Intent you can just use ActivityName.this or here VcardActivity
See this SO answer for a good explanation of using which kind of Context when.
Context Docs

Categories

Resources