2017-01-09 2 views
0

Я пытаюсь заполнить recyclerview из задачи async. и в задаче Async данные извлекаются через вызов API и помещаются в таблицу SQLite, тогда список заполняется из таблицы SQLite. Список не отображается при первой загрузке. Но когда я закрываю приложение и снова открываю приложение, список заполняется. Это общая проблема, которую нужно решать должным образом или мне не хватает чего-то еще?Recyclerview из SQLite отображает пустую страницу в первый раз

public class KingsActivity extends AppCompatActivity { 
    RecyclerView mRecyclerView; 
    RecyclerView.Adapter mAdapter; 
    RecyclerView.LayoutManager mLayoutManager; 
    List<King> kingList=new ArrayList<King>(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     Log.d("method_track","onCreate"); 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     //To avoid the load on the main thread 
     new DownloadDataAsync().execute(this); 


    } 

    public class DownloadDataAsync extends AsyncTask<Context, Integer, Context> { 

     @Override 
     protected Context doInBackground(Context... ctx) { 
      downloadData(ctx[0]); 
      return ctx[0]; 
     } 

     @Override 
     protected void onProgressUpdate(Integer... progress) { 
     } 

     @Override 
     protected void onPostExecute(Context result) { 

      Log.d("method_track","PostExecute"); 
      Cursor kingsRows=DatabaseHelper.getInstance(result.getApplicationContext()).getData(DatabaseHelper.TABLE_WESTEROS_KINGS); 
      kingsRows.moveToFirst(); 
      while(kingsRows.moveToNext()){ 
       String kingName=kingsRows.getString(kingsRows.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_NAME)); 
       int battleCount=kingsRows.getInt(kingsRows.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_BATTLE_COUNT)); 
       int rating=kingsRows.getInt(kingsRows.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_RATING)); 
       kingList.add(new King(kingName,rating,battleCount)); 

      } 
      kingsRows.close(); 


      mRecyclerView = (RecyclerView)findViewById(R.id.my_recycler_view); 

      mLayoutManager = new LinearLayoutManager(result); 
      mRecyclerView.setLayoutManager(mLayoutManager); 
      mAdapter = new KingsAdapterRC(kingList,result); 
      mRecyclerView.setAdapter(mAdapter); 
      mAdapter.notifyDataSetChanged(); 
     } 

     public void downloadData(final Context ctx){ 
      // Get a RequestQueue 
      RequestQueue queue = HttpRequestHandler.getInstance(ctx.getApplicationContext()). 
        getRequestQueue(); 

      String url ="http://starlord.hackerearth.com/gotjson"; 
      // Request a string response from the provided URL. 
      StringRequest stringRequest = new StringRequest(Request.Method.GET, url, 
        new Response.Listener<String>() { 
         @Override 
         public void onResponse(String response) { 
          // Display the first 500 characters of the response string. 
          //Log.d("result_check",response.substring(0,500)); 

          loadToDb(response,ctx); 
          populateList(ctx); 
          calculateRating(ctx); 
          logRatings(ctx); 


          //mTextView.setText("Response is: "+ response.substring(0,500)); 
         } 
        }, new Response.ErrorListener() { 
       @Override 
       public void onErrorResponse(VolleyError error) { 
        Log.d("result_check","Error"); 
        //mTextView.setText("That didn't work!"); 
       } 
      }); 

      // Add a request to RequestQueue. 
      HttpRequestHandler.getInstance(ctx).addToRequestQueue(stringRequest); 
     } 
     protected void loadToDb(String jsonResponse,Context ctx){ 
      DatabaseHelper.getInstance(ctx.getApplicationContext()).truncate(DatabaseHelper.TABLE_WESTEROS_DATA); 
      try { 
       JSONArray jsonArray = new JSONArray(jsonResponse); 
       for(int i=0;i<jsonArray.length();i++){ 
        JSONObject jsonObj = (JSONObject)jsonArray.get(i); 
        Iterator<String> iter = jsonObj.keys(); 
        HashMap<String,String> fieldVales=new HashMap<String, String>(); 
        while (iter.hasNext()) { 
         String key = iter.next(); 
         try { 
          Object value = jsonObj.get(key); 
          fieldVales.put(key,value.toString()); 

         } catch (JSONException e) { 
          // Something went wrong! 
          Log.e("loadTodb",e.toString()); 
         } 
        } 
        DatabaseHelper.getInstance(ctx.getApplicationContext()).insert(DatabaseHelper.TABLE_WESTEROS_DATA,fieldVales); 
       } 

      } catch (Throwable t) { 
       //Log.e("My App", "Could not parse malformed JSON: \"" + json + "\""); 
      } 
     } 
     protected void populateList(Context ctx){ 
      List<King> kingList=new ArrayList<King>(); 
      String[] kings; 
      int kingsCount=0; 
      String sql="SELECT DISTINCT "+DatabaseHelper.KEY_WESTEROS_ATTACKER_KING+ " FROM "+ DatabaseHelper.TABLE_WESTEROS_DATA 
        +" WHERE "+ DatabaseHelper.KEY_WESTEROS_ATTACKER_KING +" <> ''"; 
      Cursor rows=DatabaseHelper.getInstance(ctx.getApplicationContext()).getReadableDatabase().rawQuery(sql, null); 
      kingsCount+=rows.getCount(); 



      String sql2="SELECT DISTINCT "+DatabaseHelper.KEY_WESTEROS_DEFENDER_KING + " FROM "+ DatabaseHelper.TABLE_WESTEROS_DATA 
        + " WHERE "+ DatabaseHelper.KEY_WESTEROS_DEFENDER_KING + " NOT IN ("+sql+ ") AND " 
        + DatabaseHelper.KEY_WESTEROS_DEFENDER_KING +" <> ''"; 

      Cursor rows2=DatabaseHelper.getInstance(ctx.getApplicationContext()).getReadableDatabase().rawQuery(sql2, null); 
      kingsCount+=rows2.getCount(); 

      kings=new String[kingsCount]; 
      int i=0; 

      if (rows.moveToFirst()) { 
       while (!rows.isAfterLast()) { 
        //your code to implement 
        kings[i]=rows.getString(rows.getColumnIndex(DatabaseHelper.KEY_WESTEROS_ATTACKER_KING)); 
        i++; 
        rows.moveToNext(); 
       } 
      } 
      rows.close(); 

      if (rows2.moveToFirst()) { 
       while (!rows2.isAfterLast()) { 
        //your code to implement 
        kings[i]=rows2.getString(rows2.getColumnIndex(DatabaseHelper.KEY_WESTEROS_DEFENDER_KING)); 
        i++; 
        rows2.moveToNext(); 
       } 
      } 
      rows2.close(); 


      DatabaseHelper.getInstance(ctx.getApplicationContext()).truncate(DatabaseHelper.TABLE_WESTEROS_KINGS); 
      for(i=0;i<kingsCount;i++){ 
       HashMap<String,String> fieldValues=new HashMap<String, String>(); 
       fieldValues.put(DatabaseHelper.KEY_WESTEROS_KINGS_NAME,kings[i]); 
       fieldValues.put(DatabaseHelper.KEY_WESTEROS_KINGS_RATING,"400"); 
       fieldValues.put(DatabaseHelper.KEY_WESTEROS_KINGS_BATTLE_COUNT,"0"); 
       DatabaseHelper.getInstance(ctx.getApplicationContext()).insert(DatabaseHelper.TABLE_WESTEROS_KINGS,fieldValues); 
      } 
     } 


     protected void calculateRating(Context ctx){ 
      Cursor battles_cur=DatabaseHelper.getInstance(ctx.getApplicationContext()).getData(DatabaseHelper.TABLE_WESTEROS_DATA); 

      if(battles_cur.moveToFirst()){ 
       while(!battles_cur.isAfterLast()){ 
        String attackingKing=battles_cur.getString(battles_cur.getColumnIndex(DatabaseHelper.KEY_WESTEROS_ATTACKER_KING)); 
        String defendingKing=battles_cur.getString(battles_cur.getColumnIndex(DatabaseHelper.KEY_WESTEROS_DEFENDER_KING)); 


        if(!attackingKing.equals("") && !defendingKing.equals("")){ 

         HashMap<String,String> whereConDfk=new HashMap<String,String>(); 
         whereConDfk.put(DatabaseHelper.KEY_WESTEROS_KINGS_NAME,defendingKing); 
         Cursor cursor1=DatabaseHelper.getInstance(ctx.getApplicationContext()).getData(DatabaseHelper.TABLE_WESTEROS_KINGS,whereConDfk); 
         double defKing_rating; 
         double defKing_battleCount; 
         if(cursor1.moveToFirst()){ 

          defKing_rating=cursor1.getDouble(cursor1.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_RATING)); 
          defKing_battleCount=cursor1.getDouble(cursor1.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_BATTLE_COUNT)); 
          cursor1.close(); 

          HashMap<String,String> whereConAtk=new HashMap<String,String>(); 
          whereConAtk.put(DatabaseHelper.KEY_WESTEROS_KINGS_NAME,attackingKing); 
          Cursor cursor2=DatabaseHelper.getInstance(ctx.getApplicationContext()).getData(DatabaseHelper.TABLE_WESTEROS_KINGS,whereConAtk); 
          Double atkKing_rating; 
          Double atkKing_battleCount; 
          if(cursor2.moveToFirst()){ 

           atkKing_rating=cursor2.getDouble(cursor2.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_RATING)); 
           atkKing_battleCount=cursor2.getDouble(cursor2.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_BATTLE_COUNT)); 
           cursor2.close(); 
           atkKing_battleCount++; 
           defKing_battleCount++; 

           Double defKing_rating_tr=Math.pow(10,(defKing_rating/400)); 
           Double atkKing_rating_tr=Math.pow(10,(atkKing_rating/400)); 

           Double defKing_rating_ex=defKing_rating_tr/(defKing_rating_tr+atkKing_rating_tr); 
           Double atkKing_rating_ex=atkKing_rating_tr/(defKing_rating_tr+atkKing_rating_tr); 

           String attackerStatus=battles_cur.getString(battles_cur.getColumnIndex(DatabaseHelper.KEY_WESTEROS_ATTACKER_OUTCOME)); 

           Double atkKing_rating_new=atkKing_rating; 
           Double defKing_rating_new=defKing_rating; 
           if(attackerStatus.equals("win")){ 
            atkKing_rating_new=atkKing_rating+(32*(1-atkKing_rating_ex)); 
            defKing_rating_new=defKing_rating+(32*(0-defKing_rating_ex)); 
           }else if(attackerStatus.equals("loss")){ 
            atkKing_rating_new=atkKing_rating+(32*(0-atkKing_rating_ex)); 
            defKing_rating_new=defKing_rating+(32*(1-defKing_rating_ex)); 
           }else if(attackerStatus.equals("draw")){ 
            atkKing_rating_new=atkKing_rating+(32*(0.5-atkKing_rating_ex)); 
            defKing_rating_new=defKing_rating+(32*(0.5-defKing_rating_ex)); 
           } 
           String update_atkKing_ratingQuery="UPDATE "+ DatabaseHelper.TABLE_WESTEROS_KINGS + " SET " 
             + DatabaseHelper.KEY_WESTEROS_KINGS_RATING+" = "+atkKing_rating_new+", " 
             + DatabaseHelper.KEY_WESTEROS_KINGS_BATTLE_COUNT+" = "+atkKing_battleCount 
             + " WHERE "+ DatabaseHelper.KEY_WESTEROS_KINGS_NAME +" =\""+attackingKing+"\""; 

           String update_defKing_ratingQuery="UPDATE "+ DatabaseHelper.TABLE_WESTEROS_KINGS + " SET " 
             + DatabaseHelper.KEY_WESTEROS_KINGS_RATING+" = "+defKing_rating_new+", " 
             + DatabaseHelper.KEY_WESTEROS_KINGS_BATTLE_COUNT+" = "+defKing_battleCount 
             + " WHERE "+ DatabaseHelper.KEY_WESTEROS_KINGS_NAME +" =\""+defendingKing+"\""; 

           DatabaseHelper.getInstance(ctx.getApplicationContext()).getWritableDatabase().execSQL(update_atkKing_ratingQuery); 
           DatabaseHelper.getInstance(ctx.getApplicationContext()).getWritableDatabase().execSQL(update_defKing_ratingQuery); 

          } 

         } 
        } 
        battles_cur.moveToNext(); 
       } 
      } 

     } 
     protected void logRatings(Context ctx){ 
      Log.d("method_track","logratings"); 
      Cursor kings_cur=DatabaseHelper.getInstance(ctx.getApplicationContext()).getData(DatabaseHelper.TABLE_WESTEROS_KINGS); 
      try { 
       while (kings_cur.moveToNext()) { 

        String name=kings_cur.getString(kings_cur.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_NAME)); 
        String rating=kings_cur.getString(kings_cur.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_RATING)); 
        String battleCount=kings_cur.getString(kings_cur.getColumnIndex(DatabaseHelper.KEY_WESTEROS_KINGS_BATTLE_COUNT)); 
        //Log.d("method_track", "logratings"); 
        Log.d("rating_inspect",name+" - "+rating+" - "+battleCount); 

       } 
      }finally { 
       kings_cur.close(); 
      } 

     } 
    } 



} 
+0

отладка вашего приложения .. это покажет вам, что именно происходит в первый раз .... попробуйте удалить mAdapter.notifyDataSetChanged(); – kgandroid

+0

dont Intialize your recycler view in onPostExecute сделать это перед вызовом asynch-задачи и обновить список адаптеров, вызвав notifyDataSetChange, как только вы получите список из asynch-задачи i, e внутри onPostExecute –

ответ

0

Здесь:

downloadData(ctx[0]); 

Проблема вызвана downloadData методом.

Метод downloadData с использованием StringRequest для получения данных с сервера. StringRequest обрабатывать все запросы на рабочих. Возврат и возврат результата с использованием Response.Listener.

doInBackground также сделано все работа сверху рабочий Thread. поэтому doInBackground метод работы Thread просто выполняет downloadData метод, не дожидаясь ответа от StringRequest.

Не нужно использовать дополнительную тему при использовании StringRequest. просто удалите AsyncTask и используйте только StringRequest, чтобы он работал правильно.

+0

Когда я использую без async-задачи, я получаю это сообщение 'I/Choreographer : Пропустили 68 кадров! Приложение может делать слишком много работы над своим основным потоком. 'И это связано с методом' calculateRating' – DharanBro

+0

@DharanBro: Да, это возможно, потому что вы также выполняете другие операции внутри 'onResponse'. поэтому просто используйте 'AsyncTask' внутри' onResponse' для выполнения других операций. –

+1

@DharanBro: создайте свой код как запрос StringRequest -> onResponse -> запустите 'AsyncTask', чтобы вызвать' loadToDb (response, ctx); 'метод в' doInBackground' и вызывать 'populateList (ctx); вычислятьRating (ctx); logRatings (ctx);' from' onPostExecute' –

0

Yo не должен вызывать залп StringRequest из doInBackground потому async task сразу выстрелил метод post execute и список будет пуст, так что он не будет показывать какие-либо данные. Просто используйте string request и после получения ответа сохраните его в своей «базе данных» и выберите из него (вы можете сохранить и получить данные с database напрямую или с помощью async-задачи).

Для использования не только StringRequest без async task и протестируйте его.

Смежные вопросы