I would like to automatically insert some crafted code to any possible parts of the target app code. This crafted code includes a "context.startService()" to contact with a remote service from another app. How can I automatically get this context instance so that I can call startService() from anywhere within the app code?
Thanks a lot in advance. Any inputs are highly appreciated.
If I understand correctly, you want to start a service from anywhere within your codebase without passing around context objects. The solution below is a way to do this but look at this post to get a better understanding of why this isn't always the best solution.
Create a class that extends from Application:
import android.app.Application;
public class MyApplication extends Application {
private static Application sInstance;
public MyApplication() {
sInstance = this;
}
public static Application getInstance() {
return sInstance;
}
}
This will give you access to your application's context so you can start a service from anywhere.
Now in some part of your code:
void foo() {
MyApplication.getInstance().startService(new Intent(MY_SERVICE));
}
create a new method, that gets your context, and then calls your service with said context, then call that method instead.
shouldnt change your code much....
Related
An extended Application class can declare global variables. Are there other reasons?
Introduction:
If we consider an apk file in our mobile, it is comprised of
multiple useful blocks such as, Activitys, Services and
others.
These components do not communicate with each other regularly and
not forget they have their own life cycle. which indicate that
they may be active at one time and inactive the other moment.
Requirements:
Sometimes we may require a scenario where we need to access a
variable and its states across the entire Application regardless of
the Activity the user is using,
An example is that a user might need to access a variable that holds his
personnel information (e.g. name) that has to be accessed across the
Application,
We can use SQLite but creating a Cursor and closing it again and
again is not good on performance,
We could use Intents to pass the data but it's clumsy and activity
itself may not exist at a certain scenario depending on the memory-availability.
Uses of Application Class:
Access to variables across the Application,
You can use the Application to start certain things like analytics
etc. since the application class is started before Activitys or
Servicess are being run,
There is an overridden method called onConfigurationChanged() that is
triggered when the application configuration is changed (horizontal
to vertical & vice-versa),
There is also an event called onLowMemory() that is triggered when
the Android device is low on memory.
Application class is the object that has the full lifecycle of your application. It is your highest layer as an application. example possible usages:
You can add what you need when the application is started by overriding onCreate in the Application class.
store global variables that jump from Activity to Activity. Like Asynctask.
etc
Sometimes you want to store data, like global variables which need to be accessed from multiple Activities - sometimes everywhere within the application. In this case, the Application object will help you.
For example, if you want to get the basic authentication data for each http request, you can implement the methods for authentication data in the application object.
After this,you can get the username and password in any of the activities like this:
MyApplication mApplication = (MyApplication)getApplicationContext();
String username = mApplication.getUsername();
String password = mApplication.getPassword();
And finally, do remember to use the Application object as a singleton object:
public class MyApplication extends Application {
private static MyApplication singleton;
public MyApplication getInstance(){
return singleton;
}
#Override
public void onCreate() {
super.onCreate();
singleton = this;
}
}
For more information, please Click Application Class
Offhand, I can't think of a real scenario in which extending Application is either preferable to another approach or necessary to accomplish something. If you have an expensive, frequently used object you can initialize it in an IntentService when you detect that the object isn't currently present. Application itself runs on the UI thread, while IntentService runs on its own thread.
I prefer to pass data from Activity to Activity with explicit Intents, or use SharedPreferences. There are also ways to pass data from a Fragment to its parent Activity using interfaces.
The Application class is a singleton that you can access from any activity or anywhere else you have a Context object.
You also get a little bit of lifecycle.
You could use the Application's onCreate method to instantiate expensive, but frequently used objects like an analytics helper. Then you can access and use those objects everywhere.
Best use of application class.
Example: Suppose you need to restart your alarm manager on boot completed.
public class BaseJuiceApplication extends Application implements BootListener {
public static BaseJuiceApplication instance = null;
public static Context getInstance() {
if (null == instance) {
instance = new BaseJuiceApplication();
}
return instance;
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onBootCompleted(Context context, Intent intent) {
new PushService().scheduleService(getInstance());
//startToNotify(context);
}
Not an answer but an observation: keep in mind that the data in the extended application object should not be tied to an instance of an activity, as it is possible that you have two instances of the same activity running at the same time (one in the foreground and one not being visible).
For example, you start your activity normally through the launcher, then "minimize" it. You then start another app (ie Tasker) which starts another instance of your activitiy, for example in order to create a shortcut, because your app supports android.intent.action.CREATE_SHORTCUT. If the shortcut is then created and this shortcut-creating invocation of the activity modified the data the application object, then the activity running in the background will start to use this modified application object once it is brought back to the foreground.
I see that this question is missing an answer. I extend Application because I use Bill Pugh Singleton implementation (see reference) and some of my singletons need context. The Application class looks like this:
public class MyApplication extends Application {
private static final String TAG = MyApplication.class.getSimpleName();
private static MyApplication sInstance;
#Contract(pure = true)
#Nullable
public static Context getAppContext() {
return sInstance;
}
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate() called");
sInstance = this;
}
}
And the singletons look like this:
public class DataManager {
private static final String TAG = DataManager.class.getSimpleName();
#Contract(pure = true)
public static DataManager getInstance() {
return InstanceHolder.INSTANCE;
}
private DataManager() {
doStuffRequiringContext(MyApplication.getAppContext());
}
private static final class InstanceHolder {
#SuppressLint("StaticFieldLeak")
private static final DataManager INSTANCE = new DataManager();
}
}
This way I don't need to have a context every time I'm using a singleton and get lazy synchronized initialization with minimal amount of code.
Tip: updating Android Studio singleton template saves a lot of time.
I think you can use the Application class for many things, but they are all tied to your need to do some stuff BEFORE any of your Activities or Services are started.
For instance, in my application I use custom fonts. Instead of calling
Typeface.createFromAsset()
from every Activity to get references for my fonts from the Assets folder (this is bad because it will result in memory leak as you are keeping a reference to assets every time you call that method), I do this from the onCreate() method in my Application class:
private App appInstance;
Typeface quickSandRegular;
...
public void onCreate() {
super.onCreate();
appInstance = this;
quicksandRegular = Typeface.createFromAsset(getApplicationContext().getAssets(),
"fonts/Quicksand-Regular.otf");
...
}
Now, I also have a method defined like this:
public static App getAppInstance() {
return appInstance;
}
and this:
public Typeface getQuickSandRegular() {
return quicksandRegular;
}
So, from anywhere in my application, all I have to do is:
App.getAppInstance().getQuickSandRegular()
Another use for the Application class for me is to check if the device is connected to the Internet BEFORE activities and services that require a connection actually start and take necessary action.
Source: https://github.com/codepath/android_guides/wiki/Understanding-the-Android-Application-Class
In many apps, there's no need to work with an application class directly. However, there are a few acceptable uses of a custom application class:
Specialized tasks that need to run before the creation of your first activity
Global initialization that needs to be shared across all components (crash reporting, persistence)
Static methods for easy access to static immutable data such as a shared network client object
You should never store mutable instance data inside the Application object because if you assume that your data will stay there, your application will inevitably crash at some point with a NullPointerException. The application object is not guaranteed to stay in memory forever, it will get killed. Contrary to popular belief, the app won’t be restarted from scratch. Android will create a new Application object and start the activity where the user was before to give the illusion that the application was never killed in the first place.
To add onto the other answers that state that you might wish store variables in the application scope, for any long-running threads or other objects that need binding to your application where you are NOT using an activity (application is not an activity).. such as not being able to request a binded service.. then binding to the application instance is preferred. The only obvious warning with this approach is that the objects live for as long as the application is alive, so more implicit control over memory is required else you'll encounter memory-related problems like leaks.
Something else you may find useful is that in the order of operations, the application starts first before any activities. In this timeframe, you can prepare any necessary housekeeping that would occur before your first activity if you so desired.
2018-10-19 11:31:55.246 8643-8643/: application created
2018-10-19 11:31:55.630 8643-8643/: activity created
You can access variables to any class without creating objects, if its extended by Application. They can be called globally and their state is maintained till application is not killed.
The use of extending application just make your application sure for any kind of operation that you want throughout your application running period. Now it may be any kind of variables and suppose if you want to fetch some data from server then you can put your asynctask in application so it will fetch each time and continuously, so that you will get a updated data automatically.. Use this link for more knowledge....
http://www.intridea.com/blog/2011/5/24/how-to-use-application-object-of-android
This might be a simple question but I just wanted to make sure I am right.
In my android application I have a constructor that uses:
activity.getApplicationContext()
The activity is passed into the constructor as a parameter.
The problem is that I am calling this class from a Service. If I make a second constructor which accepts the Service as a parameter and uses service.getApplicationContext? Will I get the same application context?
The easiest way to get the application context is:
Create a class App that extends android.app.Application
public class App extends Application {
public static Context context;
#Override public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
}
Modify your AndroidManifest.xml 's <application> tag to have the attribute android:name="your.package.name.App".
Any time you need the application context, just get it from App.context.
Application is always initialized first whether your process runs, whether it's an activity, a service, or something else. You will always have access to the application context.
Will I get the same application context?
Yes. You can check the android documentation, they have provided
getApplicationContext()
Return the context of the single, global Application object of the current process.
So it should not be changed for the whole application process.
Please also take a note of this:
getApplicationContext() generally should only be used if you need a Context whose lifecycle is separate from the current context, that is tied to the lifetime of the process rather than the current component.
Correct me if I'm wrong.
Thanks
There is only one application context, so you should get the same one. You can have just one constructor that takes a Context, you don't really need two. Or if you wanted to make sure that you are getting the application context, and not, say, an activity one, you can have your constructor take Application as a parameter which is a Context.
You can go for getApplicationContext() if you wanna get context of whole application. If you want to get context of current class you can use getBaseContext() instead.
I have adapted yuku's answer with a non static direct context reference.
Create a class domain.company.pseudo.ApplicationName which extends android.app.Application.
package hypersoft.systems.android;
import android.app.Application;
public class Starbox extends Application {
public static Starbox instance;
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
}
In this sample, my full application package name is hypersoft.systems.android.starbox.
Now, modify your AndroidManifest.xml <application> tag to have the attribute android:name="hypersoft.systems.android.Starbox", and be sure the Starbox.java class file is located in the project component directory: android rather than starbox.
With all this done, you can now import hypersoft.systems.android.Starbox, and in your code you can get the ApplicationContext by calling Starbox.instance.getApplicationContext()
Successfully compiling with build tools 26 and api 26 (Android 8.0) with min sdk version 14 (4.0).
Application Context add Activity Context both are different.Downcasting is risky .Use this code to use context object .
public class App extends Application {
public static Context context;
#Override public void onCreate() {
super.onCreate();
context = getApplicationContext();
}
}
In Your Activities and in fragments Class :
Conetext context=App.context;
I have followed this tutorial to use SQLite db in my android app.
Since I am a beginner I'm having problems understanding "context" parameter used in the example.
I want to call adapter and insert/update/delete records from a class that does not extend activity which in this example stands for context.
Now I don't know what to pass in the adapter as context, since I'm not calling adapter from activity.
Can someone please explain this?
Pass the ActivityName.this as class context as argument to the adapter class's constructor
the ActivityName is the name of the Activityclass in which you are calling the adapter
you could imagine that the context defines WHERE/WHEN the sqlite database exists. sqlite databases do not exist on their own, they exist within the confines of your activity, thus in your activity's context.
for the next steps you must understand that the context is a dynamic "thing" (in reallife you could imagine it as someone's HERE and NOW). the context is individual to the activity and its moment, just as your here and now are yours and yours only and change over time.
if you are calling a class from within your activity, then this does the trick (passing the activity's context from within the activity itself is OK - sorta like you saying to your buddy: this is how i am feeling NOW).
public class MyActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Context contextNew = this;
myClass(contextNew);
an easy all around solution (panacea) would be to create a static Context variable (contextVariable) inside MyActivity and access it directly from without via: MyActivity.contextVariable. but that does not work, because you get an error when you try to declare/use a static Context variable.
So, if you plan on using sqlite inside a service that is NOT called from within the main activity, like, for example, a service triggered by a broadcast receiver (neither a service nor a receiver have a context per se), then you must access the original application's context from within said receiver.
accessing the original activity's context is simple, but far from obvious.
this works for me (thanx #ZiGi and #Cristian):
import android.app.Service;
import android.content.Context;
public class BatchUploadGpsData extends Service {
public Context contextNew;
#Override
public void onCreate() {
contextNew = getApplicationContext();
this is an example from working code that uploads navigation data to a database on the web every time the android device connects to a WIFI network. i have a receiver listening to connectivity changes (existing as a separate class called directly "from" Manifest file).
i hope that this makes sense, if you want more detail on this, check out this post of mine where i have the complete (barebones) code for said receiver.
As you see in the example, there is a context passed to the ToDoAdapter. You can pass activity as a context or activity.getApplicationContext(). Read about context here.
I have a class:
public class DbAdapter {
private DbHelper dbHelper;
private SQLiteDatabase db;
private final Context context;
...
}
and i want have it available in all activities. The class provides access to my sqlite database.
What is the most elegant and neat way to do it? I thought about creating object in each activity (it should "connect" me to the same database, right?).
You can achieve it extending the Application class. Google has this to say about it:
Base class for those who need to
maintain global application state. You
can provide your own implementation by
specifying its name in your
AndroidManifest.xml's
tag, which will cause that class to be
instantiated for you when the process
for your application/package is
created.
There is normally no need to subclass
Application. In most situation, static
singletons can provide the same
functionality in a more modular way.
If your singleton needs a global
context (for example to register
broadcast receivers), the function to
retrieve it can be given a Context
which internally uses
Context.getApplicationContext() when
first constructing the singleton.
I have done it myself like this:
public class App extends Application {
private DbHelper dbHelper;
#Override
public void onCreate() {
super.onCreate();
dbHelper = new DbHelper(this);
}
public SQLiteDatabase getDatabase(){
return dbHelper.getWritableDatabase();
}
#Override
public void onTerminate() {
super.onTerminate();
dbHelper.close();
}
}
Then you just access it calling getApplicationContext.getDatabase()
You may take a look at the Singleton Pattern, it gives the opportunity to make a class have only one object created and to make this object accessible from everywhere. Hope this helps.
I think the best way to implement this is to use Service. The Service will keep reference to DbAdapter and all your activities will connect to the Service. When activity is connected to the service it'll keep the reference to it and every time it needs db access it'll use to get the DbAdapter. Using this approach you'll have control over your db connection. If no activities are connected to the service than no one is using the db connection and you can free it.
Have a look at ContentProviders. They're made for accessing data. And regardless of all the emphasis on "sharing data between applications" in the link, they don't have to be public - you can use them as a centralized way to access data in your app.
This blog entry on 'Writing Your Own ContentProvider' shows some code for setting up a ContentProvider that works within one application.
I have a singleton that holds a lot of information on my App (ACCU.class).
I'm using the application context to do a single initialization and single finishing.
One of the key features is another singleton called IMCDefinition that reads from a raw resource named imc.xml. If I call the line IMCDefinition.getInstance(getResources().openRawResource(R.raw.imc)); from an Activity Context it works. From an Application context it doesn't...
Following goes the code:
public class App extends Application
{
public App()
{
IMCDefinition.getInstance(getResources().openRawResource(R.raw.imc));
ACCU.getInstance(this);
System.out.println("Global ACCU Object Initialized");
}
}
Done! You don't get to mess with the Constructor in this class. onCreate() is the way to go. Put your code there. Forget about the question. Should i put this in a separate answer?