Загрузить локальные данные, если интернет-соединение недоступно

У меня есть приложение для Android, которое отображает данные из моей внешней базы данных из нескольких таблиц. Все работает нормально, в то время как подключение к интернету доступно (все данные поступают по URL-ссылке, и они были проанализированы с залпом). Но как я могу сохранить и загрузить последние данные, когда Интернет недоступен.

Каков наилучший способ сделать это. Я новичок в Android....

Пожалуйста помоги.

2 ответа

Решение

Обычно Volley и HttpStack, который он использует, позволяют беспрепятственно кэшировать ответы. Это, однако, зависит от ваших ответов и запросов. Эти стратегии кэширования подчиняются определению http-кэша. Если вы хотите иметь другое поведение для Volley, вы можете просто переопределить эту часть. в основном, когда вы создаете запрос, вы можете переопределить

protected Response<String> parseNetworkResponse(NetworkResponse response) {

и вместо

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

ты сделаешь

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);

Который в основном будет обновлять кэш каждый раз, когда сервер так указывает, но всегда будет возвращать кэш в течение 30 дней, если не произойдет изменений.

Обратите внимание, что здесь вы можете получить 2 обратных вызова в ответе или в одном ответе и 1 ошибку (в случае отсутствия сети). первым будет кеш.

ОБНОВИТЬ:

если вы добавите (что прокомментировано в примере выше):

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

это повлияет на обновление кэша. в этом случае событие не будет пытаться обновить кэш в течение 30 дней. В этом случае вы вернете 1 ответ.

Обратите внимание, что я никогда не рекомендовал бы подобное решение, потому что кэш нужно обновлять, особенно если вы хотите подделать кеш на POST-запросах, как в вашем случае.

Получение 2 обратных вызовов на самом деле не является проблемой, так как вы можете обрабатывать этот случай для пользователя и обновлять пользовательский интерфейс, когда это необходимо. Кроме того, если вы хотите иметь больше контроля, вы можете узнать, какой из кеша, а какой образует сеть, путем реализации вашего

ResponseDelivery

или продлить

ExecutorDelivery

а затем проверить на параметр

mResponse.intermediate

и решить, что делать потом. ResponseDelivery - это тот, который вызывает обратные вызовы.

Обновить

Подобный вопрос и примеры здесь

Если вам нужно хранить только небольшой кусок данных, используйте SharedPreferences. Если у вас большие данные, используйте SQLite.

Используйте приведенный ниже код для создания и обновления БД SQLite

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 

}

где MyApplication - статический класс для хранения прочитанных значений.

Другие вопросы по тегам