How to save online data with SharedPreference in Android

独自空忆成欢 提交于 2020-01-11 14:42:17

问题


I want to show 3 fragments in my Activity and load data from json in any fragments! I need to show website data into Recyclerview with OkHTTP v3 library.
I want to show this data for offline, I mean, if user turn off data/wifi show this datas for offline. but i do not want use SQLite Database!
For this idea i use SharedPreference for save data and when disable network show show to offline data from this Preference.
I write below codes, but when disable network not show me datas the offline!!

AsyncTask codes:

public class freeDataInfo {
    private Context mContext;
    private String ServerAddress = freeServer_IP.getFreeIP();

    public void getFreeDataInfo(Context context) {
        mContext = context;
        //new getInfo().execute(ServerAddress + "limit=10");
        new getInfo().execute(ServerAddress);
    }

    private class getInfo extends AsyncTask<String, Void, String> {
        EventBus bus = EventBus.getDefault();
        private String ou_response;
        private List<DataModel> infoModels = new ArrayList<>();
        private ProgressDialog dialog;

        @Override
        protected void onPreExecute() {
            //CustomProcessDialog.createAndShow(mContext);
            //infoModels = new ArrayList<>();

            // Initiate Progress
            dialog = new ProgressDialog(mContext);
            this.dialog.setMessage("شکیبا باشید...");
            this.dialog.show();

            infoModels.clear();
        }

        @Override
        protected String doInBackground(String... params) {
            OkHttpClient client = new OkHttpClient();

            //String url = (String) params[0];
            Request request = new Request.Builder()
                    //.url(ServerAddress + "limit=10")
                    .url(ServerAddress)
                    .cacheControl(CacheControl.FORCE_NETWORK)
                    .build();

            Response response;
            try {
                response = client.newCall(request).execute();
                ou_response = response.body().string();
                response.body().close();
                if (ou_response != null) {
                    try {
                        JSONObject postObj = new JSONObject(ou_response);
                        JSONArray postsArray = postObj.optJSONArray("result");

                        for (int i = 0; i <= postsArray.length(); i++) {
                            JSONObject postObject = (JSONObject) postsArray.get(i);


                            int id = postObject.getInt("id");
                            Log.d("id", String.valueOf(id));
                            String title = postObject.getString("title");
                            String description = postObject.getString("full_description");
                            String image = postObject.getString("image");
                            String category = postObject.getString("categoryName");
                            String date = postObject.getString("date");
                            String url = postObject.getString("url");

                            Log.d("Data", "Post ID: " + id);
                            Log.d("Data", "Post title: " + title);
                            Log.d("Data", "Post image: " + image);
                            Log.d("Data", "Post url: " + url);
                            Log.d("Data", "---------------------------------");

                            //Use the title and id as per your requirement
                            infoModels.add(new DataModel(id, title, description, category, date, url, image));
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                        Log.e("error", String.valueOf(e));
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
                Log.e("error2", String.valueOf(e));
            }
            return ou_response;
        }

        @Override
        protected void onPostExecute(String result) {
            //CustomProcessDialog.dissmis();

            //Stop Progress
            if (dialog.isShowing()) {
                dialog.dismiss();
            }

            if (result != null) {
                bus.post(new MyEvent("forfragment1", infoModels));
            } else {
                //Toast.makeText(mContext, "اتصال اینترنت خود را بررسی کنید", Toast.LENGTH_LONG).show();

                if (isNetworkStatusAvialable(mContext)) {
                    //Here your normal parsing while network available
                    SharedPreferences app_preferences1 = PreferenceManager.getDefaultSharedPreferences(mContext);
                    SharedPreferences.Editor editor = app_preferences1.edit();
                    editor.putString("jsonResponse", ou_response);
                    editor.commit();

                } else {
                    final SharedPreferences app_preferences1 = PreferenceManager.getDefaultSharedPreferences(mContext);
                    String response = app_preferences1.getString("jsonResponse", "");

                    try {
                        JSONObject postObj = new JSONObject(response);
                        JSONArray postsArray = postObj.optJSONArray("result");

                        for (int i = 0; i <= postsArray.length(); i++) {
                            JSONObject postObject = (JSONObject) postsArray.get(i);

                            int id = postObject.getInt("id");
                            Log.d("id", String.valueOf(id));
                            String title = postObject.getString("title");
                            String description = postObject.getString("full_description");
                            String image = postObject.getString("image");
                            String category = postObject.getString("categoryName");
                            String date = postObject.getString("date");
                            String url = postObject.getString("url");

                            Log.d("Data", "Post ID: " + id);
                            Log.d("Data", "Post title: " + title);
                            Log.d("Data", "Post image: " + image);
                            Log.d("Data", "Post url: " + url);
                            Log.d("Data", "---------------------------------");

                            //Use the title and id as per your requirement
                            infoModels.add(new DataModel(id, title, description, category, date, url, image));
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                        Log.e("error", String.valueOf(e));
                    }
                }

            }
        }
    }

    public static boolean isNetworkStatusAvialable(Context context) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivityManager != null) {
            NetworkInfo netInfos = connectivityManager.getActiveNetworkInfo();
            if (netInfos != null)
                if (netInfos.isConnected())
                    if (netInfos.isAvailable())
                        return true;
        }
        return false;
    }
}

Fragment codes:

public class free_fragment extends Fragment {

    private RecyclerView mRecyclerView;
    private free_recycler_adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
    private List<DataModel> dataModels = new ArrayList<DataModel>();
    private List<DataModel> infoModels = new ArrayList<>();
    //private ArrayList<DataModel> dataModels;

    private Context context;
    private boolean isDataFetched;
    private boolean mIsVisibleToUser;
    private View view;

    @Override
    public View onCreateView(LayoutInflater inflater,
                             ViewGroup container, Bundle savedInstanceState) {

        view = inflater.inflate(R.layout.fragment_free_layout, container, false);

        context = getContext();

        if (mIsVisibleToUser) {
            LoadData();
        }

        ///----- RecyclerView -----
        mRecyclerView = (RecyclerView) view.findViewById(R.id.pdf_RecyclerView);
        mRecyclerView.setHasFixedSize(true);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        mAdapter = new free_recycler_adapter(context, dataModels);
        mRecyclerView.setAdapter(mAdapter);

        return view;
    }

    @Subscribe
    public void onEvent(MyEvent event) {
        List<DataModel> dataModels = event.getInfoModels();
        if (dataModels.size() > 0) {
            dataModels.remove(dataModels.size() - 1);
            mAdapter.notifyItemRemoved(dataModels.size());
            //mAdapter.setLoaded();
        }
        if (event.fragmentTag.equals("forfragment1")) {
            mAdapter.add(dataModels);
            isDataFetched = true;
            mAdapter.notifyDataSetChanged();
        }
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        mIsVisibleToUser = isVisibleToUser;
        if (isVisibleToUser && !isDataFetched && getContext() != null) {
            context = getContext();
            LoadData(); //Remove this call from onCreateView
        }
    }

        private void LoadData() {
            freeDataInfo dataInfo = new freeDataInfo();
            // here getMainDataInfo() should return the server response
            dataInfo.getFreeDataInfo(context);
        }

        @Override
        public void onResume() {
            super.onResume();
            EventBus.getDefault().register(this);
        }

        @Override
        public void onPause() {
            EventBus.getDefault().unregister(this);
            super.onPause();
        }

Adapter codes:

public class free_recycler_adapter extends RecyclerView.Adapter<free_recycler_adapter.ViewHolder> {
    private List<DataModel> mDateSet;
    private Context context;
    private ArrayList<DataModel> mModels;

    // Provide a suitable constructor (depends on the kind of dataset)
    public free_recycler_adapter(Context context, List<DataModel> dataSet) {
        this.context = context;
        this.mDateSet = dataSet;
    }

    public free_recycler_adapter(ArrayList<DataModel> models) {
        this.mModels = models;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public free_recycler_adapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        // create a new view
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.free_card_layout, parent, false);

        // create ViewHolder
        return new ViewHolder(view);
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder viewHolder, final int position) {

        // - get data from your itemsData at this position
        // - replace the contents of the view with that itemsData

        viewHolder.free_titleText.setText(Html.fromHtml(mDateSet.get(position).getTitle()));

        Glide.with(context)
                .load(mDateSet.get(position).getImage())
                .placeholder(R.drawable.ic_download_image)
                .override(200, 200)
                .crossFade(500)
                .into(viewHolder.free_avatarImage);

        viewHolder.free_descText.setText(Html.fromHtml(mDateSet.get(position).getDescription()));
        viewHolder.free_descText.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                v.getContext().startActivity(new Intent(v.getContext(), ContentPage.class)
                        .putExtra("title", mDateSet.get(position).getTitle())
                        .putExtra("desc", mDateSet.get(position).getDescription())
                        .putExtra("image", mDateSet.get(position).getImage())
                        .putExtra("url", mDateSet.get(position).getUrl())
                        .putExtra("category", mDateSet.get(position).getCategory())
                        .putExtra("date", mDateSet.get(position).getDate()));
            }
        });

    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mDateSet.size();
    }

    public void remove(int position) {
        mDateSet.remove(position);
        notifyItemRemoved(position);
    }

    public void clear() {
        mDateSet.clear();
        notifyDataSetChanged();
    }

    public void add(List<DataModel> models) {
        mDateSet.addAll(models);
        notifyDataSetChanged();
    }

    public void update(List<DataModel> models) {
        mDateSet.clear();
        mDateSet.addAll(models);
        notifyDataSetChanged();
    }

    // inner class to hold a reference to each item of RecyclerView
    public static class ViewHolder extends RecyclerView.ViewHolder {

        public TextView free_titleText, free_descText;
        public ImageView free_avatarImage;

        public ViewHolder(View itemLayoutView) {
            super(itemLayoutView);

            free_titleText = (TextView) itemLayoutView.findViewById(R.id.pdf_card_title);
            free_descText = (TextView) itemLayoutView.findViewById(R.id.pdf_card_content);
            free_avatarImage = (ImageView) itemLayoutView.findViewById(R.id.pdf_card_image);

        }
    }
}

How can i fix this and show data (offline) with sharedPreferences? Thanks all <3


回答1:


you can save the origin JsonObject to SharedPreference with toString() method. When offline, read the String from SharedPreference and then recreate JsonObject with that String, and process it as you just get it from the server



来源:https://stackoverflow.com/questions/38282787/how-to-save-online-data-with-sharedpreference-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!