I forked Apollo recently from CyanogenMod project for experimenting, this app uses custom views for theming mainly. I am usung AndroidStudio an this IDE requires custom views to implement View.isInEditMode() method to bypass context loading when editing layout.
So I have something like this:
public class CustomButton extends ImageButton
implements OnClickListener, OnLongClickListener {
private final SomeUtililtyClass mResources;
public CustomButton(final Context context, final AttributeSet attrs) {
super(context, attrs);
// Handle editing layout from IDE
if(!isInEditMode()) {
mResources = new SomeUtililtyClass(context);
// do more stuff
}
// some methods
}
Problem is that i have some methods that use mResources that is not always initialized giving me a Java compiler error.
There is an standard way to handle this or should I initialize mResources to null or an empty object?
It is necesary to remove the final modificator?
There's not really a standard way or tricks, it's up to you.
View.isInEditMode() returns true when your class is instantiated under the IDE (the class is really executed), so it's a run-time method rather than a compiler-known value.
In the case you propose, initializing to null and removing final would do it, seems simple. Or maybe,if you want to keep the final keyword, you can pass a NULL context tho the SomeUtilityClass constructor if isInEditMode() and make it just return without executing the conflicting operation.
In my experience, normally doing in the first line of the constructor
if (isInEditMode()) return;
is enough for most classes. But if your class does custom drawing (onDraw / draw / dispatchDraw) you'd need to check it there as well.
At the moment it looks like Eclipse doesn't process click handlers, but this can change in the future.
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
I'm trying to follow an Android tutorial for caching bitmaps and looking at the sample code confuses me.
The code defines some utility classes as ImageFetcher, ImageResizer, and ImageWorker. Fetcher extends Resizer and Resizer extends Worker.
When Fetcher is called in the tutorial it invokes this code.
public ImageFetcher(Context context, int imageSize) {
super(context, imageSize);
init(context);
}
The super class Resizer invokes this code
public ImageResizer(Context context, int imageSize) {
super(context);
setImageSize(imageSize);
}
And finally the super class Worker invokes this code
protected ImageWorker(Context context) {
mResources = context.getResources();
}
What I don't understand is what resizing has to do with fetching, what working has to do with resizing, and why these classes are arranged like this. I'm trying to emulate something like this for my own app and was looking at what would be considered a good example but it only confused me further. I naively thought that you could simply have a class that does the fetching, not extended from one that did resizing (since they seem completely separate actions to me).
Yes I am new to Java as well.
EDIT: Sorry, I just started programming in Java. It turned out to be a problem with an out of range array access... I am used to error messages about this kind of thing being automatic...
(using Netbeans 7.0.1)
I have been customizing JTextArea and JTable. I do so by adding a new Java class to my project and then declaring it extends the particular class I want (in my case, either JTextArea or JTable).
I had been using it normally, adding these new classes to JDialogs and JInternalFrames without any problem. I do so by just dragging it to my JDialog or JInternalFrame...
But recently, for some reason, I started getting this error messages "Component cannot be instantiated. Please make sure it is a JavaBeans component."
The JInternalFrames that were accepting the old customized classes still accepts them. But if I try to add the new customized class, it gives me that error message and, afterwards, it starts showing the same message to the old customized classes too...
Something really weird is going on. I copied the same code of a (previously) customized class to a new class (changing the name of the class, of course). Then I try to add this to my JInternalFrame. It gives me the error message! If, before this, I try to add the same customized class (with the original name), it adds the class normally....
This is annoying and I can't solve it. Can anyone help me please?
Thanks a lot for this answer but, if you want to know the reason here you are.
Typically this appears on two position:
an overridden method on your component.
a normal method on your component.
For example:
package UI.Components;
public class LabelComponent extends javax.swing.JLabel {
private javax.swing.JLabel label;
public TextFieldComponent() {
label = new javax.swing.JLabel(_label);
add(label);
}
#Override
public void setText(String text) {
label.setText(text);
}
}
The method setText(String text) is called say in the supper class constructor then it the overridden new method would be called in the case of the (label) variable which is used on this method still no being initialized so a java.lang.NullPointerException will be thowed.
solution:
1) try ... catch:
#Override
public void setText(String text) {
try {
label.setText(text);
} catch (Exception e) {
}
}
2) check:
use null initialization on declaration
private javax.swing.JLabel label = null;
then check on the method
#Override
public void setText(String text) {
if(label != null)
label.setText(text);
}
3)use initialization on declaration:
private javax.swing.JLabel label = label = new javax.swing.JLabel();
and then use setText method in your constructor
label.setText(_label);
note:
in the case of reason (2) a normal method on your component, it is the same as (1) but you may call the method before initialize the variable or assign null to the variable before calling the method and so on and it can being solved by the same ways.
I too faced the same problem, after some search in the web I found the solution for this problem. I don't have a deep understanding of why and how this problem occurs, but I can share with you the solution I found.
When you get such error msg, goto the menu View-->IDE Log or you can open the log from windows_user_Home\.netbeans\7.0\var\log
In that log you have to locate the error msg you got, for example,
INFO [org.netbeans.modules.form.BeanSupport]: Cannot create default instance of: test.Application1
java.lang.NullPointerException
at test.Application1.initLabel(Application1.java:906)
So the problem is in line 906 of your .java file. Open that file and comment those lines and then you will able to overcome the problem.
You can add the component to the Form or jInternalFrame or ...
After adding the component, you can again uncomment those lines. Just Clean and Build your project.
Hope this helps..
Goodluck
reachSDK
I have encountered the similar problem, however in different context.
I have two separate projects, a swing built user interface, and another one that poses as class library.
I added a class to the class library, headed over to the user interface, and implemented this newly added class from the library into the swing interface project in shape of an existing custom JFrame. So what happened to me now that the class loader of course could not find the class because the library project required compiling. The issue was fixed by compiling it.
I have found one answer that appears to say I should create a separate class and make a static MyApplication object and make a get method. Then any class can call MyApplication.get() to retrieve the context.
Is there any other cleaner way? This is my situation:
I have a class A and a class B. Class A contains an object from class B (let's call the object b). In class A I call, "b.play()". However, I get a null pointer exception because class B needs to pass a context to the MediaPlayer.create() method.
Until now I threw together a hack and from class A I called.... "b.play(this)" and simply passed the context to B. However that is pretty ugly and looks like a bad use of OOP.
Any thoughts?
This problem seem to arise a lot in Android development. One solution to obtaining a reference to a specific Context is subclassing the Application and grab a reference to the Context which you want.
public class MyApplication extends Application {
private Context context;
#Override
public onCreate() {
super.onCreate();
this.context = getApplicationContext() // Grab the Context you want.
}
public static Context getApplicationContext() { return this.context; }
}
This solution however requires that you specify the name of your subclass in your manifest.
<application
android:name=".MyApplication"
</application>
You can then use this anywhere in your application like this in non-activity classes.
MyApplication.getContext(); // Do something with the context! :)
If class B requires a Context to operate, then I don't see any problem having class A provide that to it (through a parameter on the play method, a parameter in a constructor, etc).
I don't think you are doing any poor OOP by providing class B the dependencies that it needs to do it's job.
Passing this around is a viable way of doing things, especially if this is the activity that creates the object in need of a Context. Sometimes, I'll put the Context into the constructor (like public MyObject(Context context){this.context = context;}), so that you don't need to send it every time. However, if your object is shared across multiple Activities, you should probably update the context it is looking at with the new Activity, though I haven't tested what happens if you use the old activity.
I've answered also here.
You can do that using ContextWrapper, as described here.
For example:
public class MyContextWrapper extends ContextWrapper {
public MyContextWrapper(Context base) {
super(base);
}
public void someMethod() {
// MediaPlayer.create(this, ...)
}
}
I'm trying to put configuration, such as URLs/etc, into a resource folder for a utility class to use. However, I don't want to pass the Context from the activities everywhere. I would like to be able to access a resource via a path name (seems like assets/ was designed for this use), without using a context to access the resource.
In this particular case, I want a singleton to use something in configuration when it's instantiated. It has no need for anything from resources besides that one time during instantiation. Therefore, having to pass in a Context every time getInstance() is called would be a complete waste.
Also, this is specific to the App's configuration, and should not be in stored in a shared system file or anything like that.
Use
Resources.getSystem().getString(android.R.string.someuniversalstuff)
You can use it ABSOLUTELY EVERYWHERE in your application, even in static constants declaration! But for system resources only.
For local resources use that solution.
You could extend the main application class and provide universal helpers there to access resources. This relieves the need for context as the application would provide the context instead of the caller. The application class is singleton style and should always be available while any portion of your application is running (including services).
public class MyApplication extends Application {
protected static MyApplication instance;
#Override
public void onCreate() {
super.onCreate();
instance = this;
}
public static Resources getResources() {
return instance.getResources();
}
}
This provides you access to:
MyApplication.getResources()....
Be sure to declare your custom application in your manifest to gain access to this. Assuming your custom application is in the root of your application's namespace:
<application
android:name=".MyApplication"
... >
I would recommend doing the following:
Rather than passing context everywhere make your activity class a singleton class with a public function that returns the context:
private static ActivityMain instance;
Initialize inside onCreate() before super.onCreate():
instance = this;
Then add these public functions to your activity:
/** Get singleton instance of activity **/
public static ActivityMain getInstance() {
return instance;
}
/** Returns context of this activity **/
public static Context getContext(){
return instance.getApplicationContext();
}
Now you can use the following anywhere in any class:
Context context = AntiMorphActivity.getContext();
String packageName = context.getPackageName();
int id = context.getResources().getIdentifier("web_page", "raw", packageName);
Unfortunately I don't think there is a real way around this. I lay mine out something like this, and also pass in the getApplicationContext() instead of the activity context.
public static AppController getAppController(Context context){
if(self == null) {
//Create instance
self = new AppController();
}
return self;
}
And then:
appController = AppController.getAppController(getApplicationContext());
The stackoverflow answer to the question below shows how to use POJO to obtain a stream to a resource, if you supply its path. This might be useful in cases you need to select a specific resource from one of many.
Is it possible to read a raw text file without Context reference in an Android library project