2017-01-13 5 views
0

APIから大量のデータをダウンロードして効率的にしたいので、1つのasyncTaskで100レコードを取得し、次に別のasyncTaskで別の数千を取得する(500個分)loadListAsynchronously(); look loadData関数と同じではなく、content,progress,loadContent();関数ですが、この関数は問題ではありません。loadListAsynchronously();アプリケーションは最初のデータをダウンロードするとフリーズ後にスムーズに動作しません。私はトランザクションを追加しようとしましたが、それは私を助けません。AsyncTaskを使用するとアプリがフリーズする

private void loadData() { 
     DottedProgressBar progressBar = (DottedProgressBar) findViewById(R.id.loadIngDots); 
     progressBar.startProgress(); 
     content = (LinearLayout)findViewById(R.id.activity_main) ; 
     progress = (RelativeLayout) findViewById(R.id.progressPage) ; 
     AsyncTask<String, Void, String> read =new AsyncTask<String, Void, String>() { 
      SharedPreferences keyValues; 
      @Override 
      protected void onPreExecute() { 
       content.setVisibility(View.GONE); 
       keyValues = getSharedPreferences(Settings.MODEL_LAST_CALL, Context.MODE_PRIVATE); 
       DisplayMetrics displaymetrics = new DisplayMetrics(); 
       getWindowManager().getDefaultDisplay().getMetrics(displaymetrics); 
       height = displaymetrics.heightPixels; 
       width = displaymetrics.widthPixels; 

       super.onPreExecute(); 
      } 

      @Override 
      protected String doInBackground(String... params) { 
       modelList = new ArrayList<>(); 

       Map<String,String> options= new HashMap<>(); 
       options.put("limit",String.valueOf(AMOUNT_OF_LOADED_modelS)); 


       ApiHelper.getModelWithParams(new Callback<ModelApiEnvelope>() { 
        @Override 
        public void onResponse(Call<ModelApiEnvelope> call, Response<ModelApiEnvelope> response) { 
         Log.i(TAG,"First call model Get response"); 
        final ModelApiEnvelope envelope = response.body(); 
         if(envelope==null) 
          Toast.makeText(MainActivity.this,getString(R.string.server_down_explanation),Toast.LENGTH_SHORT).show(); 
         else{ 
         try { 
          final Dao<Model,Integer> modelDAO = getHelper().getmodelDAO(); 
          final Dao<Submodel,Integer> submodelDAO=getHelper().getsubmodelDAO(); 
          TransactionManager.callInTransaction(getHelper().getConnectionSource(), 
            new Callable<Void>() { 
             public Void call() throws Exception { 
         modelList=envelope.getData(); 
              Log.i(TAG,"LoadData loop Start"); 
         for(final model m: modelList){ 
          m.setLogo(m.getLogo()+"?width="+width/2+"&height="+height); 
          m.setLanguage(m.getLanguage().substring(0,2)); 
          if(m.getLanguage().equals("uk")) 
           m.setLanguage("ua"); 
          if(m.getsubmodels().size()!=0){ 
            for(final submodel e: m.getsubmodels()){ 
             e.setLanguage(m.getLanguage()); 
             submodelDAO.createOrUpdate(e); 
            } 
            } 
          try { 
               modelDAO.createOrUpdate(m); 
           }catch (SQLException e) {e.printStackTrace();} 
         } 

              return null;} 
            }); 
          if(envelope.getData().isEmpty()){ 
           SharedPreferences.Editor editor = sharedPreferences.edit(); 
           long time = System.currentTimeMillis(); 
           editor.putString(Settings.model_LAST_CALL , Long.toString(time)); 
           editor.apply(); 
          } 
          else 
           loadListAsynchronously(); 
         } catch (SQLException e) { 
          Log.i(TAG," message "+e.getMessage()) ; e.printStackTrace(); 
         }} 
         loadContent(); 
         content.setVisibility(View.VISIBLE); 
         progress.setVisibility(View.GONE); 

        } 
        @Override 
        public void onFailure(Call<modelApiEnvelope> call, Throwable t) { 
         Log.i(TAG,"ERROR"+ t.getMessage()); 
         Toast.makeText(MainActivity.this,getString(R.string.server_down_explanation),Toast.LENGTH_LONG).show(); 

         loadContent(); 


        } 
       },MainActivity.this,options, keyValues.getString(lang,"0")); 
      return null; 
      } 
    @Override 
     protected void onProgressUpdate(Void... values) { 
      super.onProgressUpdate(values); 
     } 

     @Override 
     protected void onPostExecute(String result) { 
      super.onPostExecute(result); 

     } 
    }; 
    read.execute(); 
} 

UPDATE:私の問題を解決するためのトランザクションを削除します。方法トレース enter image description here

UPDATE 2を追加しました。それは、データベースへの何千ものセービングのトランザクションをUiに固定しているようです。

+0

あなたがAsyncTaskを実行する/呼び出す方法を示してください。 – greenapps

+0

パラメータとしてコールバック関数を持つ関数をdoInbackGroundで呼び出すことはできません。 onResponse()がトリガーされるのを待つことはできません。 – greenapps

+0

が非同期タスクコールを追加しました。だから私はこれのような何かでリファクタリングする必要がありますか?結果を表示するにはprogressView-> api_call->を表示する(asyncTaskを実行してデータをロードし、ループの最後にprogressViewを隠す)? – Expiredmind

答えて

0

Retrofit1とAsyncTaskのコールバックは互換性がありません。これに

public interface Api { 
    void getModelWithParams(Callback<Something> callback); 
} 

public interface Api { 
    Something getModelWithParams(); 
} 

その後レトロフィットは、非同期実行のサポートを提供することはありません、あなたはAsyncTask.doInBackgroundメソッド内でその行のメソッドを実行することができますあなたはこのようなものから、あなたのAPIインターフェイスを変更する必要があります。

その他のオプションは、そのインターフェイス定義にとどまり、Retrofitメソッドを直接(AsyncTaskのラッピングなしで)呼び出すことです。問題は、あなたのさらなるロジックが重くないかどうかです。なぜなら、onResponseはUIスレッド上で実行され、フリーズを引き起こし、一般的に問題の根本的な原因であるからです。

0

わかりました私は、非同期タスクからコールバックを取り除くが、そのはまだ私のアプリをfrezzes:

public void loadListAsynchronously(){ 
     Log.i(TAG,"LoadListAsychnronulsy"); 
     AsyncTask<String, Void, String> load =new AsyncTask<String, Void, String>() { 
      @Override 
      protected String doInBackground(String... params) { 
       Log.i(TAG,"loadListAsynchronusly start"); 
           final List<model> modelList = envelope.getData(); 
           try { 
            final Dao<Model,Integer> modelDAO = getHelper().getModelDAO(); 
            final Dao<Submodel,Integer> submodelDAO=getHelper().getSubmodelDAO(); 
            TransactionManager.callInTransaction(getHelper().getConnectionSource(), 
              new Callable<Void>() { 
               public Void call() throws Exception { 
            int i=0; 
            for(model m: modelList){ 
              i++; 
              m.setLanguage(m.getLanguage().substring(0,2)); 
              if(m.getLanguage().equals("uk")) 
               m.setLanguage("ua"); 
              if(m.getsubmodels().size()!=0){ 
               for(final submodel e: m.getsubmodels()){ 
                e.setLanguage(m.getLanguage()); 
                submodelDAO.createOrUpdate(e); 
               } 
              } 
              try {modelDAO.createOrUpdate(m); Log.i(TAG,"model created :::: "+i);} 
              catch (SQLException e) {e.printStackTrace();} 
             } 
                return null;} 
              }); 
           } catch (SQLException e) { 
            Log.i(TAG," message "+e.getMessage()) ; e.printStackTrace(); 
           } 
           SharedPreferences keyValues = getSharedPreferences(Settings.model_LAST_CALL, Context.MODE_PRIVATE); 
           SharedPreferences.Editor keyValuesEditor = keyValues.edit(); 
           long time = System.currentTimeMillis(); 
           keyValuesEditor.putString(lang, Long.toString(time)); 
           keyValuesEditor.commit(); 
           Log.i(TAG,"all models succesfull added"); 
       return null; 
      } 

      @Override 
      protected void onPostExecute(String o) { 
       Toast.makeText(MainActivity.this,getString(R.string.models_updated),Toast.LENGTH_LONG).show(); 
       super.onPostExecute(o); 
      } 
     };load.execute(); 
    } 


    private void loadTest(final boolean firstCall) { 
     modelList = new ArrayList<>(); 
     SharedPreferences keyValues; 
     keyValues = getSharedPreferences(Settings.model_LAST_CALL, Context.MODE_PRIVATE); 
     Map<String,String> options= new HashMap<>(); 
     if(firstCall) 
     options.put("limit",String.valueOf(AMOUNT_OF_LOADED_modelS)); 
     else 
      options.put("offset",String.valueOf(AMOUNT_OF_LOADED_modelS)); 


     ApiHelper.getModelWithParams(new Callback<modelApiEnvelope>() { 
      @Override 
      public void onResponse(Call<modelApiEnvelope> call, Response<ModelApiEnvelope> response) { 
       envelope=response.body(); 
       if(firstCall) 
       loadData(); 
       else 
       loadListAsynchronously(); 
      } 
      @Override 
      public void onFailure(Call<modelApiEnvelope> call, Throwable t) { 
       Log.i(TAG,"ERROR"+ t.getMessage()); 
       Toast.makeText(MainActivity.this,getString(R.string.server_down_explanation),Toast.LENGTH_LONG).show(); 

      } 
     },MainActivity.this,options, keyValues.getString(lang,"0")); 
    } 
+0

forループ内でAsyncTask内で更新するオブジェクトの数はいくつですか?それはいくらか大きな額ですか? –

+0

かなり大きい〜約3-4千円 – Expiredmind

+0

私はあなたがAndroidスタジオのMethodプロファイラツールについて読んで、メインスレッドをブロックしているかどうかを確認する必要があると思う - それがアプリのフリーズの根本原因になるからです。 UIを正確にブロックしている関数を正確に表示します。ここでは推測することができますし、そのツールはあなたの問題に関する正確な情報を提供します。 –

関連する問題