2017-01-09 5 views
0

非同期タスクからrecyclerviewを入力しようとしています。非同期タスクでは、データはAPI呼び出しによってフェッチされ、SQLiteテーブルにプッシュされ、SQLiteテーブルからリストが生成されます。最初のロード時にリストが表示されません。しかし、私は、アプリケーションを閉じて、アプリを再び開くと、リストが作成されます。これは、適切に対処する必要がある一般的な問題ですか、それとも他に何か不足していますか?ここでSQLiteのRecyclerviewは初めて空のページを表示します

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あなたのリサイクラビューをonPostExecute内で初期化するasynchタスクを呼び出す前にそれを行い、notifyDataSetChangeを呼び出すことによってアダプタのリストを更新すると、asynchタスクi、e内のリストはonPostExecute内にある –

答えて

0

downloadData(ctx[0]); 

downloadData方法によって引き起こされる問題。

StringRequestを使用してサーバーからデータを取得する方法。 StringRequestワーカースレッドに対するすべての要求を処理し、結果を返します。Response.Listenerを使用して戻します。

doInBackgroundもすべてワーカースレッドで処理されます。のでメソッドの作業スレッドStringRequestから応答を得るのを待つことなくdownloadDataメソッドを実行するだけです。

StringRequestを使用する場合は余分なスレッドを使用する必要はありません。ちょうどAsyncTaskを取り除き、正しく動作させるためにStringRequestだけを使用してください。 async taskはすぐpost execute方法を撮影し、それがどのようなデータが表示されないように、あなたのリストが空になりますので、

+0

非同期タスクなしで使用すると、 'I/:68フレームをスキップ!アプリケーションは主スレッドであまりにも多くの作業をしている可能性があります.'これはメソッド 'calculateRating'のためです – DharanBro

+0

@DharanBro:はい、これは' onResponse'メソッド内で他の操作を行っているためです。他の操作を行うために 'onResponse'の中で' AsyncTask'を使用してください。 –

+1

@DharanBro:あなたのコードをStringRequestリクエストとして呼び出す - > onResponse - > 'doInBackground'の' loadToDb(response、ctx); 'メソッドを呼び出す' AsyncTask'を実行し、 'onPostExecute'の' populateList(ctx); calculateRating(ctx); logRatings(ctx); 'onPostExecute'から –

0

doInBackgroundからボレーStringRequestを呼び出すべきではありません。単にstring requestを使用して、応答を取得した後、データベースに保存してそこから取得します(databaseからデータを直接保存するか、非同期タスクを使用して保存できます)。

StringRequestを使用せず、async taskを使用しないでテストしてください。

関連する問題