Android Load from SharedPreferences in background - android

I have the following code successfully loading from SharedPreferences
List<MyObject> oList = new ArrayList<MyObject>();
// Get JSON Data from storage.
HashSet<String> oStrings = new HashSet<String>();
oStrings = (HashSet<String>) oSharedPrefs.getStringSet(IConstants.MY_OBJECT_LIST, null);
if (oStrings != null && oStrings.size() > 0)
{
Gson oGson = new Gson();
for (String strJSONObject : oStrings)
{
MyObject oObject = oGson.fromJson(strJSONObject, MyObject.class);
oList.add(oObject);
}
}
return oList;
The problem is, this is running on the UI thread & as the SharedPreferences JSON strings get larger, this can cause my app to pause for a few seconds.
How would I go about loading this data in the background then retrieving the object list?

You can use a AsyncTask for this:
public class LoadFromShared extends AsyncTask<Void, Void, List<MyObject>>{
private OnLoadingDoneListener mListener;
public interface OnLoadingDoneListener{
public void onDone(List<MyObject> result);
}
public void setOnLoadingDoneListener(OnLoadingDoneListener listener){
this.mListener = listener;
}
#Override
protected List<MyObject> doInBackground(Void... params) {
List<MyObject> oList = new ArrayList<MyObject>();
// Get JSON Data from storage.
HashSet<String> oStrings = new HashSet<String>();
oStrings = (HashSet<String>) oSharedPrefs.getStringSet(IConstants.MY_OBJECT_LIST, null);
if (oStrings != null && oStrings.size() > 0)
{
Gson oGson = new Gson();
for (String strJSONObject : oStrings)
{
MyObject oObject = oGson.fromJson(strJSONObject, MyObject.class);
oList.add(oObject);
}
}
return oList;
}
protected void onPostExecute(List<MyObject> result) {
if(mListener!=null={
mListener.onDone(result);
}
};
}
An then in your main:
LoadFromShared loader = new LoadFromShared();
loader.setOnLoadingDoneListener(new OnLoadingDoneListener(){
#Override
onDone(List<MyObject> result){
//do your stuff here
}
};);
loader.execute();
No guarantee for correct typing ;)

Related

Access shared preferences from a helper class

I have a fragment that calls a helper class in order to make a jsonRequest with Volley.
Upon response, the helper class creates a custom object, but in order to set it up, it needs to check some values stored in Shared Preferences.
The problem is that I can't access getSharedPreferences inside the helper class.
public class MyDataHandler {
ArrayList<MyItem> itemsArrayList = new ArrayList<>();
public List<MyItem> getAll(Boolean completed, String current, final MyAsyncResponse callBack) {
String url = "https://my.api/" + current;
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(
Request.Method.GET,
url,
null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for (int i = 0; i < response.length(); i++) {
try {
JSONObject jsonObject = response.getJSONObject(i);
MyItem myItem = new MyItem();
if (!completed) {
SharedPreferences sharedPreferences = getSharedPreferences("MyApp", MODE_PRIVATE); // this doesn't work
if (sharedPreferences.getBoolean("someKey", false)) {
// set properties in MyItem
}
}
itemsArrayList.add(myItem);
} catch (JSONException e) {
e.printStackTrace();
}
}
if (null != callBack) callBack.processFinished(itemsArrayList);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
);
AppController.getInstance().addToRequestQueue(jsonArrayRequest);
return itemsArrayList;
}
How can I access Shared Preferences if this class isn't attached to any particular activity?
I assume that you are instantiating MyDataBaseHandler as "getAll" is a non static function
create a constructor and a member variable like this :-
MyDataBaseHandler{
Context context;
public MyDataHandler(Context context){ //pass your activity here
this.context=context;
}
// write rest of your code
}
now you can use this context member variable and access your shared perefrence using context.getSharedPreference("MyApp", Context.MODE_PRIVATE).

I have parsed the JSON Data in a Gridview and now I want to make it available offline

Is there a way to save the JSON data at the phone so that you can see the data if your phone is offline?
And what would be the best option to cache data ? SharedPreferences or SQLite database
Here is my code, which i am using to Parse JSON:
if (InternetConnection.checkConnection(getApplicationContext()))
new GetDataTask().execute();
class GetDataTask extends AsyncTask<Void, Void, Void> {
private static final String KEY_ICONURL ="http://droid.hol.es/images/"; ;
ProgressDialog dialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(Exit_View_Activity.this);
dialog.show();
}
#Nullable
#Override
protected Void doInBackground(Void... params) {
jsonObject = JSONParser.getDataFromWeb();
try {
if (jsonObject != null) {
if(jsonObject.length() > 0) {
JSONArray array = jsonObject.getJSONArray(Keys.KEY_INFO);
int lenArray = array.length();
if(lenArray > 0) {
for(int jIndex = 0; jIndex < lenArray; jIndex++) {
MyDataModel model = new MyDataModel();
JSONObject innerObject = array.getJSONObject(jIndex);
String name = innerObject.getString(Keys.KEY_NAME);
String viewtype = innerObject.getString(Keys.KEY_VIEWTYPE);
String image = innerObject.getString(Keys.KEY_ICON);
String Constantfilter = cat_id.replaceAll("[^0-9,]","");
Log.i("CONSTANT :",Constantfilter);
String[] numbers = Constantfilter.split(",");
for (int i=0;i<numbers.length;i++) {
Log.i("Number: ", numbers[i]);
if(numbers[i].equals(Keys.CONSTANT_CAT)) {
if (innerObject.getString(Keys.KEY_VIEWTYPE).equals("exit") || innerObject.getString(Keys.KEY_VIEWTYPE).equals("grid,exit")) {
model.setName(name);
model.setView_type(viewtype);
model.setId(id);
model.setImage(KEY_ICONURL + image);
model.setCat_id(cat_id);
model.setGrid_order_id(grid_order_id);
list.add(model);
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
dialog.dismiss();
if (list.size() > 0) {
try {
adapter.notifyDataSetChanged();
dataPath = objectToFile(list);
editor.putString("key_name5",dataPath); // Saving string
// Save the changes in SharedPreferences
editor.commit(); // commit changes
// pref.getString("key_name5", null);
// list = (ArrayList<MyDataModel>)objectFromFile(dataPath);
Snackbar.make(findViewById(R.id.parentLayout), pref.getString("key_name5", null), Snackbar.LENGTH_LONG).show();
} catch (IOException e) {
e.printStackTrace();
}
If your data is structured and you want to access it in parts, you should better use SQLite.
If you just want to cache this data and you will use it completely in future better use SharedPref as you won't create schema for it hence SQLite will be a waste of resource and time both.
Hi You can create a class with any name for example I have created "LocalSharedPrefrences"
public class LocalSharedPrefrences {
private static final String strSharedPrefName = "AppPrefrence";
private static final String homePageJosn = "homePageJosn";
public static void saveHomePageJosnData(Context context, String JsonData) {
SharedPreferences pref = context.getSharedPreferences(strSharedPrefName, context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putString(homePageJosn, JsonData);
editor.commit();
}
public static String getHomePageJosnData(Context context) {
SharedPreferences pref = context.getSharedPreferences(strSharedPrefName, context.MODE_PRIVATE);
String JsonData = pref.getString(homePageJosn, "");
return JsonData;
}
}
And then you can use these functions to save and get json data as below:
LocalSharedPrefrences.saveHomePageJosnData(Context,JsonDataToSave);
String getJsonData = LocalSharedPrefrences.getHomePageJosnData(Context)
Yes, You can save your json data and and you can use it in offline by using SharedPreferences in android.
First you need to java class i.e. pojo class using Json, Convert that json into above class object.
To save that json -->
private SharedPreferences preferences;
preferences = context.getSharedPreferences("Name", Context.MODE_PRIVATE);
editor = preferences.edit();
editor.putString("your Key String", gson.toJson(here will be your json class object));
editor.commit();
To retrieve That Json-->
gson.fromJson(preferences.getString("your same Key String", null), your json class.class);
In this you will get object of that pojo class i.e. converted json class object.

How can i print arraylist from class AsyncTask?

I want to print an ArrayList. I have receive value arraylist from class AsyncTask, in MainActivity, I have value ArrayList, but when I print ArrayList, my app is not working. Please help me!
MainActivity
{
executeLoadProduct();
arraylistgroup = new ArrayList<String>();
arraylistgroup=TaskLoadProductGroup.getvaluearraylist();
String[] mStringArray = new String[arraylistgroup.size()];
mStringArray = arraylistgroup.toArray(mStringArray);
for (int i = 0; i < mStringArray.length; i++) {
System.out.println("string is2" + (String) mStringArray[i]);
}
executeLoadProduct
private void executeLoadProduct() {
// execute task load product
loadProductGroup = new TaskLoadProductGroup(MainActivity.this);
loadProductGroup.execute();
}
AsyncTask
public class TaskLoadProductGroup extends AsyncTask<String, Void, ArrayList<String>> {
private ActionBarActivity actionBarActivity;
private Context context;
private static ArrayList<String> arrayListgroup;
public TaskLoadProductGroup(ActionBarActivity actionBarActivity) {
this.actionBarActivity = actionBarActivity;
this.context = actionBarActivity.getApplicationContext();
}
#Override
protected void onPreExecute() {
///show progress loading
super.onPreExecute();
}
#Override
protected ArrayList<String> doInBackground(String... url) {
ArrayList<String> listProductgroup = null;
try {
Server server = new Server();
ResListProduct resListProduct = server.getListProducts(context);
//init list item for listview home product
listProductgroup = initItemProduct(resListProduct);
} catch (Exception e) {
}
return listProductgroup;
}
public static ArrayList<String> initItemProduct(ResListProduct rsProduct) {
List<GroupProduct> groups = rsProduct.getGroups();
arrayListgroup = new ArrayList<String>();
for (GroupProduct group : groups) {
// add header group
String s = group.getName();
arrayListgroup.add(s);
}
getvaluearraylist();
// getVarialty();
return arrayListgroup;
}
public static ArrayList<String> getvaluearraylist()
{
return arrayListgroup;
}
#Override
protected void onPostExecute(ArrayList<String> listProductgroup) {
super.onPostExecute(listProductgroup);
}
}
I couldn't identify why are you doing so complex code to print the ArrayList. You can just print that inside onPostExecute method like this,
#Override
protected void onPostExecute(ArrayList<String> listProductgroup) {
super.onPostExecute(listProductgroup);
for (String value : listProductgroup){
Log.d("myTag", value);
}
}
OR
Use loadProductGroup.execute().get() method, but remember this will freeze your UI.

Asynchronous call to server being blocked by bluetooth LE Scan

I have an Activity which constructs a RESTManager class (used to make an asynchronous call to the server and return data to the Activity).
However, after I construct my RESTManager and call the server using
//Retrieve data from server
RESTManager m = new RESTManager(this,getApplicationContext());
//Set the data list
m.delegate=this;
m.retrieveRoomData();
the server call does not go through until I turn off bluetooth scanning.
However, I start my bluetooth scan immediately after the RESTManager as such:
beaconManager = BeaconManager.getInstanceForApplication(this);
beaconManager.setBackgroundScanPeriod(1100l);
beaconManager.setBackgroundBetweenScanPeriod(100l);
beaconManager.setForegroundScanPeriod(1100l);
beaconManager.setForegroundBetweenScanPeriod(100l);
//Set the custom BeaconLayout for iBeacons
if (myPref.getBoolean("layoutSet", true)) {
beaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:0-3=4c000215,i:4-19,i:20-21,i:22-23,p:24-24"));
backgroundPowerSaver = new BackgroundPowerSaver(this);
Log.v("Beacon Layout", "Beacon Layout Set");
myPref.edit().putBoolean("layoutSet", false).apply();
myPref.edit().commit();
}
beaconManager.bind(this);
I am not getting any error.
Is there any reason why my AsyncTask from RESTManager would hang from the bluetooth scans?
Relevant code:
RESTManager class
public class RESTManager {
private DateTime lastUpdate = DateTime.now();
public AsyncResponse delegate=null;
private SharedPreferences mPrefs;
private SharedPreferences.Editor preferenceEditor;
private ArrayList<RoomData> roomDataList = new ArrayList<RoomData>();
private ArrayList<MeetingData> meetingDataList = new ArrayList<MeetingData>();
private Activity currentActivity;
private Context context;
public RESTManager(Activity currentActivity, Context context) {
this.currentActivity = currentActivity;
this.context = context;
mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
}
//Todo update meeting data logic
public ArrayList<MeetingData> retrieveMeetingDataFromServer() {
return null;
}
public void retrieveRoomData() {
new CallServerForRoomData().execute();
}
//TODO add timestamping logic.
private class CallServerForRoomData extends AsyncTask<String, Void, String> {
String myJsonData = "";
#Override
protected String doInBackground(String... params) {
//If the data isn't cached, call the server.
if (!mPrefs.contains("RoomData")) {
try {
setupHttpClient();
HttpClient myClient = new HttpClient(RequestMethod.GET, "http://10.184.46.217:9012/v1/rooms", new HttpHeaders(), null, null);
myClient.connect();
HttpResponse mR = myClient.processResponse();
myJsonData = mR.getServerResponseAsString();
System.out.println(myJsonData);
preferenceEditor = mPrefs.edit();
preferenceEditor.putString("RoomData", myJsonData);
preferenceEditor.commit();
setRoomDataList(convertRoomDataJson(myJsonData));
return "server";
} catch (HttpClientException e) {
e.printStackTrace();
}
}
//If it is cached, retrieve the data locally.
else {
setRoomDataList(convertRoomDataJson(mPrefs.getString("RoomData", "NULL")));
return "local";
}
return "Done";
}
protected void onPostExecute(final String result) {
delegate.dataFinishedRetrieving(getRoomDataList());
// setRoomDataList(convertRoomDataJson(myJsonData));
currentActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(context, "Data retrieved on " + result + " storage", Toast.LENGTH_SHORT).show();
}
});
}
}
/**
* AsyncTask for retrieving a room's meeting data.
* Pass in the room's unique identifier as a parameter of the execute method.
*/
//TODO add timestamping logic
private class CallServerForMeetingData extends AsyncTask<String, Void, String> {
String myJsonData = "";
#Override
protected String doInBackground(String... params) {
try {
setupHttpClient();
HttpClient myClient = new HttpClient(RequestMethod.GET, "http://10.184.146.217:9012/v1/room/" + params[0] + "/schedule", new HttpHeaders(), null, null);
myClient.connect();
HttpResponse mR = myClient.processResponse();
myJsonData = mR.getServerResponseAsString();
} catch (HttpClientException e) {
e.printStackTrace();
}
//Set the converted MeetingData to the RoomData object
for (RoomData e : roomDataList) {
if (e.getObjectId() == params[0]) {
e.setMeetingData(convertMeetingDataJson(myJsonData));
}
}
return "Done";
}
}
//Initializes the HTTPClient and attaches it to the application lifecycle.
public void setupHttpClient() {
HttpCacheManager.init(Application.getAppContext());
}
public ArrayList<MeetingData> convertMeetingDataJson(String JsonData) {
final Gson gson = initCustomGSON();
Type MeetingDataListType = null;
if (JsonData != "") {
MeetingDataListType = new TypeToken<ArrayList<MeetingData>>() {
}.getType();
}
return (gson.fromJson(JsonData, MeetingDataListType));
}
public ArrayList<RoomData> convertRoomDataJson(String JsonData) {
final Gson gson = initCustomGSON();
Type RoomDataListType = null;
if (!JsonData.equals("")) {
RoomDataListType = new TypeToken<ArrayList<RoomData>>() {
}.getType();
roomDataList = (gson.fromJson(JsonData, RoomDataListType));
}
roomDataList = (gson.fromJson(JsonData, RoomDataListType));
for (RoomData e : roomDataList) {
Log.v("RoomData name", e.getName());
Log.v("RoomData roomId", e.getObjectId());
//Log.v("RoomData imageUrl", e.getImageUrl());
if (e.getBeacons() != null) {
Log.v("Number of beacons", e.getBeacons().toString());
}
}
return roomDataList;
}
/**
* Initializes the GSON Json Decoder with the custom JodaTime serializers.
*
* #return
*/
public Gson initCustomGSON() {
final GsonBuilder builder = new GsonBuilder();
JodaTimeConverters converter = new JodaTimeConverters();
converter.registerAll(builder);
return builder.create();
}
public ArrayList<RoomData> getRoomDataList() {
return roomDataList;
}
public void setRoomDataList(ArrayList<RoomData> roomDataList) {
this.roomDataList = roomDataList;
}
public void setMeetingDataListForRoom(RoomData whichRoom) {
new CallServerForMeetingData().execute(whichRoom.getObjectId());
}
}

Break AsyncTaskResult<ArrayList<HashMap<String, String>>> into another list

Is there any way to break AsyncTaskResult>>
into to list ?
or get like 30,40,.. value of it only?
i have a Async class and it return the result of webservice fetch to adapter.
now because of huge data i want to split the result into seperate segment with passing
number of result to async class.
here is myasync class :
protected AsyncTaskResult<ArrayList<HashMap<String, String>>> doInBackground(
String... arg0) {
String xml = "Get String from my web service class"
myXmlParsingClass myparser = new myXmlParsingClass (xml, "getitem");
myparser .runParser();
AsyncTaskResult<ArrayList<HashMap<String, String>>> myresult = new AsyncTaskResult<ArrayList<HashMap<String, String>>>(myXmlParsingClass .getParsedData());
return myresult ;
}
and my asynctaskresult :
public class AsyncTaskResult<T> {
private T result = null;
private Exception error = null;
public T getResult() {
return result;
}
public Exception getError() {
return error;
}
public AsyncTaskResult(T result) {
super();
this.result = result;
}
public AsyncTaskResult() {
super();
}
public AsyncTaskResult(Exception error) {
super();
this.error = error;
}
this is what i have done so far :
in the getview method inside my adapter i made second method to pass a number to async class:
MyAsyncClass ma = new MyAsyncClass(myview,userid,5);
in MyAsyncClass :
public MyAsyncClass ( View context,String _id) {
this.targetCtx = context ;
id = _id;
}
public MyAsyncClass ( View context,String _id,int _ID_To_Show) {
this.targetCtx = context ;
id = _id;
ID_To_Show= _ID_To_Show;
}
and on PostExecute method :
if(ID_To_Show >0 ){
MySecondAdapter Madapter = new MySecondAdapter(targetCtx, myresult.getResult(),ID_To_Show);
mylist.setAdapter(Madapter);
}else{
MySecondAdapter Madapter = new MySecondAdapter(targetCtx, myresult.getResult());
mylist.setAdapter(Madapter);
and finally in MySecondAdapter i added this :
public MySecondAdapter(View a, ArrayList<HashMap<String, String>> id,int _ID_To_Show) {
idfromhayoolafetch = id;
myinflater = (LayoutInflater) AppContext.getAppContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ID_To_Show= _ID_To_Show;
}
public MySecondAdapter(View a, ArrayList<HashMap<String, String>> id) {
idfromhayoolafetch = id;
myinflater = (LayoutInflater) AppContext.getAppContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
if(ID_To_Show>0){
return ID_To_Show;
}else{
return idfromhayoolafetch.size();
}
}
this approch show the amount of item i want to show in each call and i can pass value to it
but is other way i can do this ?
problem is i cant ask hayoola to limit the value in respond.
Such a request should be handled by server it self.
As in server should accept number of items to return and only send that many items.
But still if you want async task to handle it you can do following:
protected AsyncTaskResult<ArrayList<HashMap<String, String>>> doInBackground(
String... arg0) {
String xml = "Get String from my web service class"
myXmlParsingClass myparser = new myXmlParsingClass (xml, "getitem");
myparser .runParser();
AsyncTaskResult<ArrayList<HashMap<String, String>>> myresult = new AsyncTaskResult<ArrayList<HashMap<String, String>>>(myXmlParsingClass .getParsedData());
ArrayList<HashMap<String, String>> result=myresult.getResult();
myresult.setResult(result.subList(0,maxItems));//maxItems=30 set it while creating async task object
return myresult ;
}

Categories

Resources