How to destroy variables instantiated in fragment after user logs out - android

I have to pull data from server for the first time when user lands on the fragment and then data should persist in the application unless user logs out but I tried this way.
public class AttendanceFragment : Fragment
{
private static ListView listView;
private static ProgressBar progress;
private static List<DA_ClassSectionAttendance> dataList=new List<DA_ClassSectionAttendance>();
// If i instantiate this variable 'dataList' here
//it will be persisted even the user logs out I know its declared as static
// because I am accessing this variable on broadcast receiver.
// But I want this re-instantiated after user logs out but HOW?
private static AttendanceListAdapter attendanceAdapter;
private static DA_Attendance daAttendance;
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// dataList = new List<DA_ClassSectionAttendance>(); if I instantiate this variable here everytime this fragment created or restores dataList.Count is zero or null
attendanceAdapter = new AttendanceListAdapter(this.Activity, dataList);
if((dataList==null || dataList.Count==0)) // pull data from server for the first time when fragment is created but I want this method call when user logs out as well.
{
GetClassSection(); // this method pulls data from server
}
//set whether MenuOption show/hide from toolbar
HasOptionsMenu = true;
}
Thank you

You can release the variables in onDestroy of the fragment. If you need to persist the data then you need to save it in DB. You can use SQLlite or realDB based on your requirement. Then when user logs out, clear the DB at that time. Hope it clears

Related

Whats make value of variable become empty or back to initialization value in lifecycle

I just curious what makes a value inside of some variable become empty again or back to its initial value in the android life cycle.
First lets take a look at how i create a variable :
public class myData {
public static String myCode = "";
public static String getData(String Choice) {
String theData = "";
if ("Code".equals(Choice) {
theData = myCode;
}
return myCode;
}
public static void setData(String setData,String Choice) {
if ("Code".equals(Choice) {
myData.myCode = setData;
}
}
}
If I want to fill the variable, i usually do this :
myData.setData("value of variable","Code");
And if I want to get the value of the variable, I usually do this :
myData.getData("Code");
I just want to know what makes my variable gone inside of android lifecycle, of course excluding when the application is closed.
I have to try to Log and show the value in onstart , oncreate, onresume and onrestart. And all of them is still have the value inside of my variable intact without any problem.
My client always tells me that my application sometimes gets crash when they open some activity. I also ask if they did something while using my application,
some of them answer that the application get crashed after they got a phone call and when the phone call is ended, the application is started with a crash.
some of them also said that when they open the application and then idle the phone withouth closing the application until the phone become black screen, and when they open it again the application get crashed.
After I check the log, the problem was the variable become empty. which is why I want to know is there another possibilites that makes the value inside of the variable become empty?
As John Lord saying, on low-end device variables might back to its initial value again if there is not enough memory.
So for future reference, I use a shared preference to counter it, here is my structure for fetching the data :
public class myActivity extends AppCompatActivity {
String myCode = "";
protected void onCreate(Bundle savedInstanceState) {
....
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("myData", Context.MODE_PRIVATE);
myCode = sharedPreferences.getString("Code",null);
....
}
#Override
protected void onResume() {
super.onResume();
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("myData", Context.MODE_PRIVATE);
myCode = sharedPreferences.getString("Code",null);
}
}
And here is how i set the data :
SharedPreferences sharedPreferences = getApplicationContext().getSharedPreferences("myData",Context.MODE_PRIVATE);
sharedPreferences.edit().putString("Code","Hello World").apply();
I hope it will be helpful for those who want to search the same thing

How to restore search results in fragment?

I have a fragment X which indeed has a RecyclerView, X has a search view, I use the search view to search something and filter the RecyclerView into few rows. After the filtering, if user clicks on some row, it goes to another fragment say Y. From there if the user clicks back it comes back to X. My task is that X should persist the search results after this coming back. What is the best approach to achieve this?
You can use a the singleton pattern to store the data!
E.g.
// DataManager.java
public class DataManager {
private static DataManager thisInstance;
// Declare instance variables
List<String> searchResultItems;
public static DataManager getSharedInstance() {
if (thisInstance == null) {
thisInstance = new DataManager();
}
return thisInstance;
}
private DataManager() {
searchResultItems = new ArrayList<>();
}
public List<String> getSearchResultItems() {
return searchResultItems;
}
public void setSearchResultItems(List<String> searchResultItems) {
this.searchResultItems = searchResultItems;
}
}
Now you can store and retrive data from everywhere:
// Setter
DataManager.getSharedInstance().setSearchResultItems(items);
// Getter
List<String> items= DataManager.getSharedInstance().getSearchResultItems();
Propertly override onSaveInstanceState in Fragment so that it will store search input - filter. Also override onCreate in such way it will apply saved filter on your RecyclerView.
Before navigating to another fragment, obtain Fragment.SavedState via FragmentManager and save it temporary in Activity which hosts your fragments. Note, this state can be lost if you do not properly save Activity state due of configuration changes (rotate) = you have to override also onSaveInstanceStatein Activity. Or simply save Fragment.SavedState in global scope (some static field, or in Application).
When navigating back to previous fragment, re-create fragment from Fragment.SavedState i. e. invoke Fragment#setInitialSavedState(Fragment.SavedState).
For more details see my research on similar topic.

Cannot retrieve saved SharedPreferences in another activity

So we're working on this Android app. We've got a login activity that receives some information when the user logs in successfully. We've got a class called SessionManager that handles saving said data to SharedPreferences.
SessionManager always retrieves SharedPreferences from the same file always. It's hardcoded in there.
public SessionManager(Context context) {
this.preferences = context.getSharedPreferences(PREFERENCE_NAME, 0);
this.editor = this.preferences.edit();
this.jsonParser = new Gson();
}
The jsonParser is there so we can save the info as a json object.
public final void storeProfile(UserProfile profile) {
this.editor.putString(STORAGE_KEY, this.jsonParser.toJson(profile));
this.editor.commit();
}
private static final String STORAGE_KEY = "PROFILE";
private String getStoredValue() {
return this.preferences.getString(STORAGE_KEY, null);
}
public UserProfile getStoredProfile() {
String val = getStoredValue();
return (val == null) ? null : this.jsonParser.fromJson(val, UserProfile.class);
}
In theory, this should mean we should be able to store the profile in one activity, then get it back in another activity, right?
Except that's not happening! It looks like I can only retrieve saved information in the same activity where it was saved!
I call storeProfile() in the login activity, then getStoredProfile() in another activity, and it returns null.
I call storeProfile() in the login activity, then getStoredProfile() in the login activity, and it returns the stored profile. It also works if two different SessionManager instances call storeProfile() and getStoredProfile().
I set the stored profile manually in the other activity, and it retrieves the manually stored profile just fine.
Is there some scope rule or something to SharedPreferences that I'm missing?
Turns out I'm a fool and I was accidentally wiping my preferences every time I tried to get them.

How to maintain the data in fragments Android

I have one Activity having 5 buttons: button1, button2, button3, button4, button5.
button1 clicks----open fragment1
button2 clicks----openf ragment2
button3 clicks----open fragment3
button4 clicks----open fragment4
button5 clicks----open fragment5
In fragment1 I am downloading data and displaying in a customized listview. In fragment2 I am downloading data and displaying in edittexts, textviews..etc.
But if I click the button1 again data is downloading again. I want to show the same view where the user comes back from fragment1 to fragment2 by clicking buttons.
How can I reach this logic? Please help me in this. If you want any information I will provide.
Thank you in advance!
EDIT : I need google chrome tab functionality in android fragments.here tabs are fragments.if you open one website in google search and open onother page in anothe tab.if you can navigate to first tab you can see the opened one only.in my case i am starting from the scratch of the fragment.how to reach chrome tab functionality in android fragments.
There are many ways to go around it. whatever data you have download you can store it either temporarily or permanently. if you want to store it temporarily you can:
use an ArrayList<HashMap<String,String>> object to store it.
or permanently using either
SQLiteDatabase or
SharedPrefrences
depending on the data type.
Now whenever you open your fragment you can check if the data already exists if not you hit the Service and get the data otherwise you can read directly from the source you have chosen.
I would use the Model-view-controller architecture on this app.
This means create a class to store this data. Use the singleton pattern when designing the class. First time the user press Button 1, upon creation of the fragment, call a method from the Model class to check if the data is downloaded or not. If it's not downloaded then fetch it, store it in the class and display it. If data is downloaded then use an method from the Model class to get the data and display it.
If you have small a amount of data to display you can use bundles or intents to store it.
UPDATE:
Below is a simple example of a singleton class that can be used to store your data and find out if your class contains initialized data or not. In my example I used as data an int value but you are free to use whatever type you want, even a class.
public class SingletonExample {
private static SingletonExample mSingleton = null;
private int mMyData;
private boolean mDataInitialized;
private SingletonExample() {
mDataInitialized = false;
}
public static SingletonExample getInstance() {
if (mSingleton == null) {
mSingleton = new SingletonExample();
}
}
return mSingleton;
}
public boolean isDataInitialized() {
return mDataInitialized;
}
public void setMyData(int myData) {
mMyData = myData;
mDataInitialized = true;
}
public int getMyData() {
return mMyData;
}
}
The singleton call you call like this:
SingletonExample mDataBank = SingletonExample.getInstance( );
mDataBank.setMyData(0);

Maintain the Persistence of Data in the Array List

I have an array list with a list of 100 records which I fetch during the availability of the internet. When the internet is not available then I am fetching it from the Application Class instance. Here is the method how I am doing it :
At the parsing step(when internet is available, after parsing the data) :
BApplication.bAppSession.setFindBData(findBDataList);
Here is the Application Class:
public class BApplication extends Application {
public static BAppSession bAppSession;
#Override
public void onCreate() {
bAppSession = new BAppSession(getApplicationContext());
}
}
Here is my Session Class:
public class BAppSession {
private Context context;
private ArrayList<FindMyBeerData> findMyBeerDataLast = new ArrayList<FindMyBeerData>();
public BeerAppSession(Context context) {
this.context = context;
}
public void setFindMyBeerData(ArrayList<FindMyBeerData> findMyBeerDataList){
this.findMyBeerDataLast = findMyBeerDataList;
}
public ArrayList<FindMyBeerData> getFindMyBeerData(){
return this.findMyBeerDataLast;
}
}
How to Fetch the Data(Offline):
findMyBDataList = BApplication.bAppSession
.getFindMyBeerData();
Problem : Everything is working fine, but the problem is when I kill the application from the task manager and restart again (when the internet is not available) , I am getting empty ArrayList. DATA IS LOST WHEN APPLICATION IS KILLED
Query: How to get the data back even if the application is killed by the user ? Suggest me any way to do the same.
From this answer - https://stackoverflow.com/a/19335539/816416 - it's clear that there's no event called when an application is killed from the task manager or killed by the system itself.
So, the better way is to save the data whenever you fetch it. This will ensure that your data is safe whether your app is killed or not. Next time when you log in, you can load the saved data.
For storing data, you can use the following:
Database SQLite : Tutorial here
Files
SharedPreferences
If you have an Activity, you can save your data inside the onDestroy() call.

Categories

Resources