I want to have a list of certain important things(which I am fetching from server every 15 seconds) which I want to have constant(or common) in my entire application. So when I move to next activity by Intents(or any other methods) I should have the list all the time. Is it possible in android ??
I want different solutions which requires as less work as possible.
Please Help..
EDIT: I think I havent made myself clear. I am not worried about how to store data..I am asking as to how can I achieve a view in which only half of the screen changes(as we move from activity to activity) while other half remains constant(doesnt move). Can it be possible ??
Your application class instance is always accesible from any activity.
All you need to do is create the application class like this:
public class YourApp extends Application {
....
}
And then modify the following line in your app AndroidManifest.xml :
<application
android:name="your.package.YourApp"
Now you can access this class everywhere:
YourApp appInstance = (YourApp)getApplication();
Use the PreferencesManager like the one below, create your POJO to access the PreferencesManager.
// TODO: Auto-generated Javadoc
/**
* The Class PreferenceManager.
*/
public class PreferenceManager {
/** The Constant TAG. */
private static final String TAG = PreferenceManager.class.getSimpleName();
/** The default shared preferences. */
private static SharedPreferences defaultSharedPreferences = null;
/**
* Inits the.
*
* #param context the context
*/
public static final void init(Context context){
defaultSharedPreferences = android.preference.PreferenceManager.getDefaultSharedPreferences(context);
log("Initialize PreferenceManager!");
UserSettings.init(context);
}
/**
* Save.
*
* #param name the name
* #param value the value
*/
static final void save(String name,String value){
if( value != null ){
Editor edit = defaultSharedPreferences.edit();
edit.remove(name);
edit.putString(name, value);
edit.commit();
}else{
Editor edit = defaultSharedPreferences.edit();
edit.remove(name);
edit.commit();
}
}
/**
* Gets the.
*
* #param name the name
* #param defaultValue the default value
* #return the string
*/
public static final String get(String name,String defaultValue){
return defaultSharedPreferences.getString(name, defaultValue);
}
/**
* Save state.
*
* #param name the name
* #param state the state
*/
public static final void saveState(String name,Bundle state){
if( state != null && state.size() > 0 ){
Parcel parcel = Parcel.obtain();
parcel.writeBundle(state);
String encodeToString = Base64.encodeToString(parcel.marshall(), Base64.DEFAULT);
PreferenceManager.save(name, encodeToString);
}else{
PreferenceManager.save(name, null);
}
log("Saved state "+name);
}
/**
* Gets the state.
*
* #param name the name
* #return the state
*/
public static final Bundle getState(String name){
log("Get state "+name);
String encryptedValue = "";
try {
encryptedValue = PreferenceManager.get(name, "");
} catch (NullPointerException e) {
return new Bundle();
}
if( "".equals(encryptedValue) ){
return new Bundle();
}else{
byte[] decode = Base64.decode(encryptedValue, Base64.DEFAULT);
Parcel parcel = Parcel.obtain();
parcel.unmarshall(decode, 0, decode.length);
parcel.setDataPosition(0);
return parcel.readBundle();
}
}
/**
* Log.
*
* #param msg the msg
*/
private static final void log(String msg){
Log.d(TAG, msg);
}
}
/**
* The Class Settings.
*/
public class UserSettings {
/** The settings bundle. */
private final Bundle settingsBundle = new Bundle(1);
/**
* Save.
*/
public final void save() {
PreferenceManager.saveState(SETTINGS_STATE_NAME, settingsBundle);
}
/**
* Restore.
*/
final public void restore() {
settingsBundle.clear();
Bundle state = PreferenceManager.getState(SETTINGS_STATE_NAME);
if (state.size() == 0) {
settingsBundle.putAll(getDefaultValuesSettings());
} else {
settingsBundle.putAll(state);
}
}
final void reset() {
settingsBundle.clear();
}
/**
* Gets the settings.
*
* #return the settings
*/
public static UserSettings getSettings() {
return settings;
}
/**
* Inits the.
*
* #param ctx the ctx
*/
public static final void init(Context ctx) {
settings.restore();
setDeviceUniqueId(ctx, settings);
}
}
Example usage:
public class YourApplication extends Application {
....
onCreate(){
....
PreferenceManager.init(getBaseContext());
}
}
Where you need your data to be stored and retrieved use the methods like below.
UserSettings.getSettings().setUser(responseVal);
UserSettings.getSettings().save();
String response = UserSettings.getSettings().getUser();
If it's large amount of data, you can store your data using Shared Preferences or SQLite DB. If it is less amount of data then you can go for static variables. If you use static variables, when any crash occurs in the app that data may lost. Hence static variables usage is less preferable.
There are lot of ways to do this :
You can store them and put in your application's SQLite database (Data is Persistent till you delete the application or delete through your application code )
See the SQLite usage here
You use Cache them in the phone memory till the time your app runs.
See Cache usage here here
You can use SQLite database to store this data and then create singleton helper to read it.
Or you can use save your data in XML or JSON format as files, then parse them to read.
Or you can create class-container for one entity of your data, make it serializable and store in SharedPreferences as ArrayList<YourDataContainer>
Related
I would like to modify the value of a int in the Notification.class in the SDK. Is this possible? Can this be achieved ?
This is the int I'd like to modify, override:
public class Notification implements Parcelable {
.......
/**
* Maximum length of CharSequences accepted by Builder and friends.
*
* <p>
* Avoids spamming the system with overly large strings such as full e-mails.
*/
private static final int MAX_CHARSEQUENCE_LENGTH = 10 * 1024;
/**
...
or alternatively, I'd like to override this method from the same class:
/**
* Make sure this CharSequence is safe to put into a bundle, which basically
* means it had better not be some custom Parcelable implementation.
* #hide
*/
public static CharSequence safeCharSequence(CharSequence cs) {
if (cs == null) return cs;
if (cs.length() > MAX_CHARSEQUENCE_LENGTH) {
cs = cs.subSequence(0, MAX_CHARSEQUENCE_LENGTH);
}
if (cs instanceof Parcelable) {
Log.e(TAG, "warning: " + cs.getClass().getCanonicalName()
+ " instance is a custom Parcelable and not allowed in Notification");
return cs.toString();
}
return removeTextSizeSpans(cs);
}
Is this possible?
In your own custom ROM? Yes.
In an Android app? No. More accurately, you have no means of affecting safeCharSequence() from your app, except perhaps on a rooted device.
Currently in my codebase I have the following class(part of it) where it shows me 2 memory leaks with the message " Do not place Android context classes in static fields (static reference to Myclass which has field context pointing to Context); this is a memory leak (and also breaks Instant Run)"
I am not sure what the alternative is. Is this a 100% memory leak ? I get the leak warning on "INSTANCE;" and "static" declaration for context. Any idea how to go about fixing it?
public enum Myclass {
INSTANCE;
public static final boolean TLS_ENABLED = true;
private static final String TAG = Myclass.class.getSimpleName();
private static final String SP = "My_class";
private static Context context;
public void init(Context context, String appKey, String appSecret) {
init(context, null, appKey, appSecret);
}
/**
* Initialize class
*
* #param context Application level context.
* #param apiUrl API url of backend server
* #param appKey Application key
* #param appSecret Application secret
* #throws IllegalArgumentException If activity instance will be passed as the context
* #throws IllegalArgumentException If application key is empty or null
* #throws IllegalArgumentException If application secret is empty or null
*/
public void init(Context context, String apiUrl, String appKey, String appSecret) {
if (null == context) { throw new NullPointerException(); }
if (!(context instanceof Application)) { throw new IllegalArgumentException("Supply my class with application context"); }
// if (TextUtils.isEmpty(apiUrl)) { throw new IllegalArgumentException("Api url can't be null or empty string"); }
if (TextUtils.isEmpty(appKey)) { throw new IllegalArgumentException("App key can't be null or empty string"); }
if (TextUtils.isEmpty(appSecret)) { throw new IllegalArgumentException("App secret can't be null or empty string"); }
this.apiUrl = apiUrl;
this.appKey = appKey;
this.appSecret = appSecret;
this.sp = context.getSharedPreferences(SP, Context.MODE_PRIVATE);
MyClass.context = context;
initManagers();
}
/**
* Initializes managers. This method must be called after constructor
* returns, as the managers during own initialization may use myclass.get()
* method.
*/
private void initManagers() {
accountManager = new AccountManager();
myclassApi = new MyclassApi(context, apiUrl);
contactManager = new ContactManager();
connectionManager = new ConnectionManager();
meetingListManager = new MeetingListManager();
}
/**
* Returns {#link Context} that was passed to
* {#link myclass#init(Context, String, String)}.
*
* #return
*/
public static Context getContext() {
return context;
}
/**
* Returns {#link SharedPreferences} instance.
*
* #return SharedPreferences
*/
public SharedPreferences getSp() {
return this.sp;
}
public static class Event<T> {
private State state = State.SUCCESS;
private Throwable t;
private T data;
private String errorMessage;
/**
* Event state. If event related to network request/response
* operations - state indicates the physical (not logical)
* success or fail of request.
*/
public enum State {
/**
* Indicates that attempt to get data or perform task successful
*/
SUCCESS,
/**
* Indicates that attempt to get data or perform task fails,
* and reason of fail is the incorrect request data
*/
FAIL,
/**
* Indicates that attempt to get data or perform task encounter an error
* mostly due to connection problem
*/
ERROR,
/**
* Indicates that attempt to get data or perform task was ignored
* according to internal state of event producer.
*/
IGNORED
}
}
It's safe to store application context in a static field, you can simple call context.getApplicationContext() on any context reference you get before storing it in a static field.
The application context is a singleton anyway and you cannot leak it.
This seems like warning from IDE if you are making sure that context will store only ApplicationContext, not Activity context you can suppress this warning using annotation.
#SuppressLint("StaticFieldLeak")
If you want to understand more about memory leaks you can check my only blog :) here
In my code I have some activities that need some extra parameters (passed as a Bundle in the Intent) to work properly. Some other need none, or have some optional extras.
How to document that in Javadoc?
One way to do that is to define public static method in your Activity to take the extra parameters and return the Intent that you're going to use to start your Activity.
Let's say you have an Activity called MainActivity and it takes an integer id and a String name. here's the code to do it.
public class MainActivity extends Activity {
private static final String BUNDLE_KEY_ID = "id";
private static final String BUNDLE_KEY_NAME = "name";
/**
* Write your documentation here
* #param context Required to create new intent
* #param id write description
* #param name write description
*/
public static Intent getIntent(Context context, int id, String name) {
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra(BUNDLE_KEY_ID, id);
intent.putExtra(BUNDLE_KEY_NAME, name);
return intent;
}
}
In Android Studio ==> Type /** above your Method Signature & Hit Enter
Studio will create documentation basics for that particular method.
/**
*
* #param args1
* #param args2
*/
private void doSomething(int args1,float args2){
}
You just need to add explanation.
/**
* Do something will Blahhh ..Blahhh..
* #param args1 Input argument used to do Blahhh ..Blahhh..
* #param args2 Input argument used to do Blahhh ..Blahhh..
*/
private void doSomething(int args1,float args2){
}
I have problem when my application crash in my "D-Activity".
MainActivity -> A Activity -> B-Activity -> C-Activity -> D-Activity
I create instance GlobalClass in MainActivity.
public static synchronized GlobalClass getInstance()
{
if(instance==null)
{
instance=new GlobalClass();
}
return instance;
}
For instance:
My app crashes in "D Activity". Android restart my app from B Activity but I lost my data in GlobalClass. There were a lot of fields String and ArrayList. How do I get them back?
You can convert your GlobalClass instance to JSON using Gson library for example. After GlobalClass is first time instantiated you can save it's JSON representation to the SharedPreferences and each time you need it if it is null you can try to read it from SharedPreferences.
Example of saving to SharedPreferences:
/**
* #return This session's config data.
*/
public Config getConfig() {
Config config = new Gson().fromJson(mPreferences.getString(KEY_CONFIG, null), Config.class);
return config;
}
/**
* Save this session's config data.
*
* #param config
* Config data.
*/
public void setConfig(Config config) {
mPreferences.edit().putString(KEY_CONFIG, new Gson().toJson(config)).commit();
}
Example of getting/setting global value:
/**
* #return Application configuration parameters.
*/
public static Config getConfig() {
if (sConfig == null)
sConfig = sPreferences.getConfig();
return sConfig;
}
/**
* Set application configuration parameters.
*
* #param config
* Config to set.
*/
public static void setConfig(Config config) {
sPreferences.setConfig(config);
sConfig = config;
}
I have a DialogView which stores settings in shared preferences. It is located in package A and i have another activity which is located in package B, which should be able to read these preferences.
So I created a wrapper class, which takes context and shared preference name and retrive these settings. When shared preferences are set at the first time everything works great, but when I change it, I got the same result, which was set at first time.
Problem is I save preference in one process and need to be able to read them in another.
So it seems like Context has changed and I am not able to retrive new context. What should I do to get up to-date shared preference?
Thank you on advance.
Please take a look at my wrapper class
public class PhotoAppWidgetSettingsProxy extends Proxy {
private final static String PREFERENCES_NAME = PhotoAppWidgetSettingsProxy.class.getName();
private final static int PREFERENCES_MODE = Context.MODE_PRIVATE;
private Context mCtx = null;
private SharedPreferences pref = null;
private SharedPreferences.Editor editor = null;
public PhotoAppWidgetSettingsProxy(String name, Context context) {
super(name, context);
mCtx = context;
pref = context.getSharedPreferences(PREFERENCES_NAME, PREFERENCES_MODE);
editor = pref.edit();
}
private final static String FRAME = "FRAME";
/**
* Sets selected frame mode
* #param frame id
*/
public void setFrameMode(int frameId){
editor.putInt(FRAME, frameId);
Log.d(PREFERENCES_NAME, "SET MODE="+frameId);
boolean success = editor.commit();
Log.d(PREFERENCES_NAME, "SET MODE="+success);
}
/**
* Gets selected frame mode
* #return frame id
*/
public int getFrameMode(){
Log.d(PREFERENCES_NAME, "GET MODE="+pref.getInt(FRAME, 0));
return pref.getInt(FRAME, 0);
}
SOLVED:
private final static int PREFERENCES_MODE = Context.MODE_MULTI_PROCESS;
private final static int PREFERENCES_MODE = Context.MODE_MULTI_PROCESS;
When accessing shared preferences/values, I have found it useful to write a CustomApplication class extending Application. I can place any necessary fields/methods in there, and easily acquire them from any of the other Android classes by using:
CustomApplication app = (CustomApplication) getApplication();
int x = app.getX();
Does that help you at all?