I have trouble unterstanding the keyPrefix of the addHelper() method.
Does it need to be unique for each BackupAgentHelper Class Instance or for each SharedPreferencesBackupHelper ?
I want to backup two or more sets of SharedPreferences:
Example:
public class PrefsBackupAgent extends BackupAgentHelper {
// Allocate a helper and add it to the backup agent
#Override
public void onCreate() {
SharedPreferencesBackupHelper user1 = new SharedPreferencesBackupHelper(this, "user1_preferences");
addHelper('prefs', user1); // <-- keyPrefix same to both addHelper Calls?
SharedPreferencesBackupHelper user2 = new SharedPreferencesBackupHelper(this, "user2_preferences");
addHelper('prefs', user2); // <--
}
}
or does it need to look like that:
public class PrefsBackupAgent extends BackupAgentHelper {
// Allocate a helper and add it to the backup agent
#Override
public void onCreate() {
SharedPreferencesBackupHelper user1 = new SharedPreferencesBackupHelper(this, "user1_preferences");
addHelper('user1', user1); // <-- or do they need to be unique for each SharedPreferencesBackupHelper ?
SharedPreferencesBackupHelper user2 = new SharedPreferencesBackupHelper(this, "user2_preferences");
addHelper('user2', user2); // <--
}
}
Which one is the correct way?
Thank you!
Your first example is correct.
public class MyBackupAgentHelper extends BackupAgentHelper {
static final String DEFAULT_PREFS = "packagename_preferences";
static final String OTHER_PREFS = "packagename_other_preference";
// A key to uniquely identify the set of backup data
static final String PREFS_BACKUP_KEY = "prefs";
#Override
public void onCreate() {
SharedPreferencesBackupHelper helper1 = new SharedPreferencesBackupHelper(this, DEFAULT_PREFS);
SharedPreferencesBackupHelper helper2 = new SharedPreferencesBackupHelper(this, OTHER_PREFS);
addHelper(PREFS_BACKUP_KEY, helper1);
addHelper(PREFS_BACKUP_KEY, helper2);
}
}
Related
I have a vocabulary room-database where words are divided into 4 categories (indicated in respective field of the table).
When the Activity launches, the method getWords() from Dao is triggered with the required argument being passed by WorkActivity
On launching the Activity I get the following error
Cannot create an instance of class space.rodionov.englishwanker.WordViewModel.
Where did I go wrong? Any help is appreciated
In Dao:
#Query("SELECT * FROM word_table WHERE category IN(:filterCategory) ORDER BY RANDOM() LIMIT 4")
Single<List<Word>> get4words(List<Integer> filterCategory);
In Repository:
public class WordRepository {
private ArrayList<Integer> categoryFilter;
private WordDao mWordDao;
//other variables
WordRepository(Application application) {
WordDatabase db = WordDatabase.getDatabase(application);
mWordDao = db.WordDao();
clearFilter();
setFilter(categoryFilter);
m4words = mWordDao.get4words(categoryFilter);
}
public void clearFilter(){
categoryFilter.clear();
}
public void setFilter(ArrayList<Integer> categoryFilter) {
this.categoryFilter = categoryFilter;
}
In ViewModel:
private ArrayList<Integer> categoryFilter = new ArrayList<>();
private WordRepository mRepository;
// declaring variables
public WordViewModel(#NonNull Application application) {
mRepository = new WordRepository(application);
//declaring
mRepository.setFilter(categoryFilter);
m4words = mRepository.get4words();
}
public void clearFilter() {
categoryFilter.clear();
}
public void setFilter(ArrayList<Integer> categoryFilter) {
this.categoryFilter = categoryFilter;
}
//other methods
In WorkActivity:
private WordViewModel wordViewModel;
public ArrayList<Integer> categoryFilter = new ArrayList<>();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences sharedPreferences = getSharedPreferences("save", MODE_PRIVATE);
boolean category0 = sharedPreferences.getBoolean("Category0", true);
boolean category1 = sharedPreferences.getBoolean("Category1", true);
//other catigories from memory ...
//
wordViewModel = new ViewModelProvider(this,
ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication()))
.get(WordViewModel.class);
wordViewModel.getListLivedata().observe(this, words -> {
adapter.submitList(words);
});
//
wordViewModel.clearFilter();
if (category0 == true) {
categoryFilter.add(0);
Log.d(TAG, "onCreate: common_words added: called");
}
//other categories
wordViewModel.setFilter(categoryFilter);
//other methods
//buildRecyclreVeiw
}
Answer is I just forgot to initialize ArrayList categoryFilter in Repository.
I have an activity on my app where a user can update their registered information stored in a remote database. When the update button is pressed the information in the database is being updated but the static variable is not changing. Here is my code thanks in advance for any help!
btUpdate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String first_name = First_name.getText().toString();
final String last_name = Last_name.getText().toString();
final String email = Email.getText().toString();
Response.Listener<String> responseListener = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonResponse = new JSONObject(response);
boolean success = jsonResponse.getBoolean("success");
if (success) {
LoginActivity.first_name = jsonResponse.getString("first_name");
LoginActivity.last_name = jsonResponse.getString("last_name");
LoginActivity.email_address = jsonResponse.getString("email");
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(UpdateInfoActivity.this);
builder.setMessage("Submission Failed")
.setNegativeButton("Retry", null)
.create()
.show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
UpdateInfoRequest updateInfoRequest = new UpdateInfoRequest(first_name, last_name, email, userID, responseListener);
RequestQueue queue = Volley.newRequestQueue(UpdateInfoActivity.this);
queue.add(updateInfoRequest);
Intent intent = new Intent(UpdateInfoActivity.this, MainActivity.class);
UpdateInfoActivity.this.startActivity(intent);
}
});
Change your code to this
if (success) {
LoginActivity.first_name = first_name;
LoginActivity.last_name = last_name;
LoginActivity.email_address = email;
}
and I wouldn't be using static variables like that if you want to have a global user profile you could do this
class User {
private static User user = null;
public String firstName = "";
private User() {}
public static synchronized User getInstance() {
if (user == null) user = new User();
return user;
}
}
to retrieve data from anywhere in project call this
String name = User.getInstance().firstName;
And to modify the data do this
User.getInstance().firstName = UserName;
First Understand that static variables are shared by all objects and methods of the class.
So we only have one instance of the static variable.
The ways to Update static variable from other class -
1.Through object.
2.Through Class name.
Enclosing the code sample.
class A{
static int val;
public A(){val=0; }
//....
}
class B{
A obj= new A();
public void updateStatic(){
obj.val=10; // updates values through object to 10
A.val=100; //updates values through class name to 100
}
//..
}
Hope it Helps
Transfer of data between activities using the static variable is not a better way in my opinion. It is bad practice. Transferring data using intents or save data in storage media and accessing from there will be the better solution.
but the static variable is not changing.
Should be... You told the code to do that
if (success) {
LoginActivity.first_name = jsonResponse.getString("first_name");
LoginActivity.last_name = jsonResponse.getString("last_name");
LoginActivity.email_address = jsonResponse.getString("email");
}
Just want to mention...
1) You update a String, not any TextView or EditText in your question, so if you expected to see a "visual change" in your app, then no, nothing will happen unless you call setText.
2) That code is wrapped in a try-catch, and could error, so check the logs for a JSONException. If those keys aren't sent back from the server, then sure, they won't update. For example, the JSON is only {"success": true }
Still, SharedPrefences should largely be preferred over static variables here.
My Arraylist Only stores one object in it. Every time a new object is entered, it overwrites the current one.
Calling method:
public void saveBookingInfo(View view) {
EditText applicantNameText = (EditText) findViewById(R.id.applicantNameTextField);
EditText itemToBurnText = (EditText) findViewById(R.id.itemToBurnTextField);
String appName = applicantNameText.getText().toString();
String appItemToBurn = itemToBurnText.getText().toString();
if (appItemToBurn.isEmpty() || appName.isEmpty()) {
Toast.makeText(BookingScreen.this, "Please fill in all fields.", Toast.LENGTH_SHORT).show();
}
else {
sendApplication.storeApplication(appName, appItemToBurn);
this.finish();
}
}
ArrayList method:
public void storeApplication(String name, String item){
ArrayList<Application> peopleAttending = new ArrayList<>(10);
peopleAttending.add(new Application(name, item));
}
You're declaring the List<Application> as local parameter to the method. Move it as a field in the class instead.
private List<Application> peopleAttending = new ArrayList<>();
public void storeApplication(String name, String item) {
peopleAttending.add(new Application(name, item));
}
You are creating a new ArrayList every time you call the method. You should create the ArrayList exactly once and pass a reference to the method, or make the reference an instance variable.
you can try changing the constructor of the class for object sendApplication
class SendApplication{
List<Application> peopleAttending = null;
public SendApplication(){
List<Application> peopleAttending = new ArrayList<Application>();
}
public void storeApplication(String name, String item) {
peopleAttending.add(new Application(name, item));
} //...... other methods follow
}
I have an app with multiple classes:
MenuActivity, MenuThread, MenuView, MenuBot, MenuBall.
In the class "MenuView" I declare all the ib objects I need:
this.ball = new MenuBall(this, bot1);
this.bot1 = new MenuBot1(this, ball);
this.thread = new MenuThread(this,bot1,ball);
As you can see i didn't create yet the object bot1 but i already use it as a parameter in the object ball, which gives me the error.
Thank you for trying to help me !
You have to change (or add other) constructors of MenuBall and MenuBot1.
Thus, for example:
public class MenuBall {
private MenuBot1 menuBot1;
(...)
// this constructor doesn't need a MenuBot1 object.
public MenuBall(MenuView menuView) {
(...)
}
// setter for the menuBot1
public void setMenuBot1(MenuBot1 menuBot1) {
this.menuBot1 = menuBot1;
}
(...)
}
public class MenuBot1 {
private MenuBall menuBall;
(...)
// this constructor doesn't need a MenuBall object.
public MenuBot1(MenuView menuView) {
(...)
}
// setter for the menuBall
public void setMenuBall(MenuBall menuBall) {
this.menuBall = menuBall;
}
(...)
}
Then in MenuView class:
ball = new MenuBall(this);
bot1 = new MenuBot1(this);
ball.setMenuBot1(bot1);
bot1.setMenuBall(ball);
thread = new MenuThread(this, bot1, ball);
(...)
I'm using Robospice with Retrofit ans ORMLite modules. Retrofit part working good. I have City model for Retrofit:
City.java:
public class City {
public int city_id;
public String name;
#SuppressWarnings("serial")
public static class List extends ArrayList<City> {
}
}
I'm taking this model from server by GET-request:
MyApi.java
public interface MyAPI {
#GET("/cities")
City.List getCities();
}
This part works fine by calling this method:
getSpiceManager().execute(mRequestCity, "city", DurationInMillis.ONE_MINUTE, new ListCityRequestListener());
and listener:
public final class ListCityRequestListener implements RequestListener<City.List> {
#Override
public void onRequestFailure(SpiceException spiceException) {
Toast.makeText(RegisterActivity.this, "failure", Toast.LENGTH_SHORT).show();
}
#Override
public void onRequestSuccess(final City.List result) {
Toast.makeText(RegisterActivity.this, "success", Toast.LENGTH_SHORT).show();
updateCities(result);
}
}
At this time i want to download city list once from server and store this list into sqlitedb by ORMLite module. I've created ORMLite model:
City.java
#DatabaseTable(tableName = "city")
public class City {
public final static String DB_CITY_ID_FIELD_NAME = "id";
public final static String DB_CITY_NAME_FIELD_NAME = "name";
#DatabaseField(canBeNull = false, dataType = DataType.INTEGER, columnName = DB_CITY_ID_FIELD_NAME)
int id;
#DatabaseField(canBeNull = false, dataType = DataType.STRING, columnName = DB_CITY_NAME_FIELD_NAME)
private String name;
public City() {
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("id = ").append(id);
sb.append(", ").append("name = ").append(name);
return sb.toString();
}
}
My RetrofitSpiceService.java looks like this:
public class RetrofitSpiceService extends RetrofitGsonSpiceService {
private final static String BASE_URL = "http://example.com/api/v1";
private final static UserFunctions userFunctions = new UserFunctions();
#Override
public CacheManager createCacheManager(Application application) throws CacheCreationException {
CacheManager cacheManager = new CacheManager();
List< Class< ? >> classCollection = new ArrayList< Class< ? >>();
// add persisted classes to class collection
classCollection.add( City.class );
// init
RoboSpiceDatabaseHelper databaseHelper = new RoboSpiceDatabaseHelper( application, "sample_database.db", 1 );
InDatabaseObjectPersisterFactory inDatabaseObjectPersisterFactory = new InDatabaseObjectPersisterFactory( application, databaseHelper, classCollection );
cacheManager.addPersister( inDatabaseObjectPersisterFactory );
return cacheManager;
}
#Override
protected Builder createRestAdapterBuilder() {
Builder mBuilder = super.createRestAdapterBuilder();
mBuilder.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
if (userFunctions.isUserLoggedIn()) {
request.addHeader("Authorization", userFunctions.getToken());
}
}
});
return mBuilder;
}
#Override
public void onCreate() {
super.onCreate();
addRetrofitInterface(MyAPI.class);
}
#Override
protected String getServerUrl() {
return BASE_URL;
}
}
I can't understand how can i store and read data from my City database? How do i need to change RetrofitSpiceService? I want download data by Retrofit and store it to database by ORMLite. My CacheManager is correct, i.e. will work properly? Maybe I misunderstand how the module Robospice-ORMLite works?
Thanks a lot!
When you make execute() call with cache key and duration Robospice will store your response into database.
getSpiceManager().execute(mRequestCity, "city", DurationInMillis.ONE_MINUTE, new ListCityRequestListener());
All following requests during one minute will get data from this cache, and then it makes network call. If you want to get data only from cache take a look on getSpiceManager().getFromCache() method. I think it's what you are looking for.