Load local data if internet connection not available

爱⌒轻易说出口 提交于 2019-12-13 07:19:12

问题


I have an android application that display data from my external Database so from several tables. Everything work fine while internet connection is available (all data come from URL link and they are been parsed with volley). But how can I save and load lastest data when internet is not available.

What is the best way to do that. Im new in android....

Please help.


回答1:


Normally Volley and also HttpStack it uses allows you to seamlessly cache responses. This however depends on your responses and requests. Those cache strategies obeys http cache definition. If You want to have different behavior for Volley you can just override this part. basically when you create a request you can override

protected Response<String> parseNetworkResponse(NetworkResponse response) {

and instead of

return Response.success(parsed, HttpHeaderParser.parseCacheHeaders(response));

you do

long now = System.currentTimeMillis();
Cache.Entry entry = HttpHeaderParser.parseCacheHeaders(response);
        entry.ttl = now + 30l * 24 * 60 * 60 * 1000;  //kepps cache for 30 days 
//entry.softTtl = now + 30l * 24 * 60 * 60 * 1000;  //will not refresh for 30 days     
        return Response.success(parsed, entry);

Which basically will refresh the cache every time the server specifies so but will always return the cache for 30 days unless changes .

Note that here you may receive 2 callbacks in response or in one response and 1 error(in case of no network). the first one will be the cache.

UPDATE:

if you add (which is commented in the example above):

entry.softTtl = now + 30l * 24 * 60 * 60 * 1000;  //will not refresh for 30 days 

this will affect the refresh of the cache. in this case it wont event try to refresh the cache for 30 days. In that case you will return 1 response.

Note that I never would recommend solution like this because cache needs to be updated, especially if you want to fake cache on POST requests as in your case.

Receiving 2 callbacks is not really an issue as you can handle this seamlesly for the user and update UI when needed. also if you want to have more control you can know which one is from the cache and which one form the network by implementing your

ResponseDelivery

or extend

ExecutorDelivery

and then check for the param

mResponse.intermediate

and decide what to do then. ResponseDelivery is the one which calls the callbacks.

Update

similar question and examples here




回答2:


if you have to store only small chunk of data then use SharedPreferences If you have large data then use SQLite

Use below code to create and update SQLite DB

public class SqlMangaeMenu 
{
SQLiteDatabase db1 = null;
private static String DBNAME = "YourLocal.db";
Context gcntxt;


public SqlMangaeMenu(Context cntxt) 
{
    // TODO Auto-generated constructor stub     

    gcntxt=cntxt;
    db1 = cntxt.openOrCreateDatabase(DBNAME, Context.MODE_PRIVATE,null);

    db1.execSQL("CREATE TABLE IF NOT EXISTS mytbl(appid varchar PRIMARY KEY,appname varchar,iconcode varchar,msgidentfier varchar,scode varchar,image blob,imagehdr blobhdr); ");

}//EOF Constructor



public void insertContent(String appid,String appname,String iconcode,String msgidentifier,String scode,Bitmap bmp,Bitmap bmphdr)
{
    ContentValues contentValues = new ContentValues();

    contentValues.put("appid", appid);
    contentValues.put("appname", appname);
    contentValues.put("iconcode", iconcode);
    contentValues.put("msgidentfier", msgidentifier);
    contentValues.put("scode", scode);  

    byte[] blob = null,blobhdr=null;
    if(bmp!=null)
    {
    ByteArrayOutputStream outStr = new ByteArrayOutputStream();
    bmp.compress(CompressFormat.PNG, 100, outStr);
    blob = outStr.toByteArray();        
    }
    contentValues.put("image", blob);

    if(bmphdr!=null)
    {
    ByteArrayOutputStream outStr1 = new ByteArrayOutputStream();
    bmphdr.compress(CompressFormat.PNG, 100, outStr1);
    blobhdr = outStr1.toByteArray();

    }
    contentValues.put("imagehdr", blobhdr);

    Log.d("db", "SQL Writing"+appid+appname+iconcode+msgidentifier+scode);

    try {
        // db1.insert("mytbl",null,contentValues);
        db1.insertWithOnConflict("mytbl", null, contentValues,SQLiteDatabase.CONFLICT_IGNORE);
    } catch (Exception e) 
    {
        // TODO: handle exception

    }


    db1.close();

}//EOF insertContent

// Deleting single contact
public void Delete_appid(String id) 
{
   db1.delete("mytbl", "appid" + "=" + id, null);

    db1.close();
}//EOF Delete_appid


public void readAppId()
{

    MyApplication.dbappid=new ArrayList<String>();      

    String appid;
    try
    {          

        Cursor c = db1.rawQuery("SELECT * FROM mytbl", null);
        //Cursor c = db1.rawQuery("SELECT MAX(ID) FROM mytbl", null);


        if(c!= null)
        {
         if (c.moveToFirst()) 
              {
                do {
                    appid=c.getString(c.getColumnIndex("appid"));


                    MyApplication.dbappid.add(appid);


                   }while(c.moveToNext());
               }


          }
        Log.d("db", "SQL Reading");
        db1.close();
        } 
     catch(Exception e)
     {
          System.out.println(e);

     }

}//EOF readAppId


public void readDataandImage()
{
    Bitmap image=null,imagehdr = null;
    //Bitmap images
    MyApplication.dbimg=new ArrayList<Bitmap>();
    MyApplication.dbhdrimage=new ArrayList<Bitmap>();

    //String
    MyApplication.dbappname=new ArrayList<String>();
    MyApplication.dbappid=new ArrayList<String>();
    MyApplication.dbiconcode=new ArrayList<String>();


    String appname,appid,iconcode;
    try
    {
        Cursor c = db1.rawQuery("SELECT * FROM mytbl", null);

        if(c!= null)
        {
         if (c.moveToFirst()) 
              {
                do {

                    image=null;imagehdr=null;
                    byte[] blob = c.getBlob(c.getColumnIndex("image"));
                    byte[] blobhdr = c.getBlob(c.getColumnIndex("imagehdr"));
                    appid=c.getString(c.getColumnIndex("appid"));
                    appname=c.getString(c.getColumnIndex("appname"));
                    iconcode=c.getString(c.getColumnIndex("iconcode"));

                    if(blob!=null)
                    {
                    image = BitmapFactory.decodeByteArray(blob, 0, blob.length);
                    }
                    if(blobhdr!=null)
                    {
                    imagehdr = BitmapFactory.decodeByteArray(blobhdr, 0, blobhdr.length);
                    }

                    //Images
                    MyApplication.dbimg.add(image);
                    MyApplication.dbappid.add(appid);

                    //String
                    MyApplication.dbappname.add(appname);
                    MyApplication.dbiconcode.add(iconcode);
                    MyApplication.dbhdrimage.add(imagehdr);



                   }while(c.moveToNext());
               }


          }
        Log.d("db", "SQL Reading");
        db1.close();
        } 
     catch(Exception e)
     {
          System.out.println(e);

     }


}//EOF readDataandImage


public int dbRowCount()
{
    int rowcnt=0;
    String countQuery = "SELECT * FROM mytbl";
    //SQLiteDatabase db = this.getReadableDatabase();
    Cursor cursor = db1.rawQuery(countQuery, null);
    rowcnt = cursor.getCount();
    cursor.close();
    db1.close();
    Log.d("db", "Numrecs"+rowcnt);
    return rowcnt;
}//EOFdbRowCount 

}

where MyApplication is a static class to hold the read values.



来源:https://stackoverflow.com/questions/36406399/load-local-data-if-internet-connection-not-available

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