Как я могу правильно использовать Asynctask?

Я разрабатываю приложение для Android, но Asynctask и Looper создают для меня больше проблем, и я не понимаю, как решить эту проблему... Это моя основная деятельность:

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public class MainActivity extends Activity {
 private ProgressDialog progress = null;
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);  


  //Check if the connectivity is available   
  CheckConnectivity check = new CheckConnectivity();
  Boolean conn = check.checkNow(this.getApplicationContext());
  //if connectivity is available
  if(conn == true){
   //Create the action bar
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {  
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);

    ActionBar actionBar = getActionBar();
    actionBar.setDisplayShowTitleEnabled(true);
    actionBar.setDisplayHomeAsUpEnabled(false);
    actionBar.setHomeButtonEnabled(false);
    actionBar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#0170a5")));
   }
   setContentView(R.layout.activity_main);
   GetNews getNews = new GetNews();
   getNews.execute();
  }else{
      connectivityMessage("Nessuna connessione presente, assicurati di avere il traffico dati oppure il Wi-Fi attivato e riprova."); 
  }
 } 

/******************************************************************************************************/
 private class GetNews extends AsyncTask<Void, Void, String>{

   @Override
   protected String doInBackground(Void... params) {
    Looper.prepare(); 
    ReadServer read = new ReadServer();
    String result = read.readserver("list_news","homepage");
    return result;
   }

   @Override
   protected void onCancelled() {
    super.onCancelled();
   }

   @Override
   protected void onPreExecute() {
    progress = ProgressDialog.show(
    MainActivity.this, null, "Caricamento notizie...");
    super.onPreExecute();
  }

    @Override
    protected void onPostExecute(String result) {
    super.onPostExecute(result);
    try {
     String url_img = null;
     String path = "http://www.MYPATH.it";

     TableLayout MainTable = (TableLayout) findViewById(R.id.main_table);
     JSONArray Jobj = new JSONArray(result);

     for (int i = 0; i < Jobj.length(); i++) {
     TableRow row = new TableRow(getApplicationContext());
     row.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT));


     JSONObject news_preview = Jobj.getJSONObject(i);
     Integer news_id = news_preview.getInt("id_articolo");
     String news_title = news_preview.getString("titolo");
     String news_image = news_preview.getString("immagine");

     // Check if image url is relative or absolute
     Pattern p = Pattern.compile("^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]");
     Matcher m = p.matcher(news_image);

     if (m.matches() == false) {
         url_img = path + news_image;
     } else if (m.matches() == true) {
        url_img = news_image;
     }

     // Call Html Parser to parse text
     HtmlParser parsed_string = new HtmlParser();
     Spanned title_nohtml = parsed_string.htmlparser(news_title);

     final ImageView img = new ImageView(getApplicationContext());
     final TextView txt = new TextView(getApplicationContext());
     LayoutParams params = new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
     img.setAdjustViewBounds(true);
     Bitmap bitmap = BitmapFactory.decodeStream((InputStream) new URL(url_img).getContent());
     Bitmap resized = null;

     int screenLayout = getApplicationContext().getResources().getConfiguration().screenLayout;
     screenLayout &= Configuration.SCREENLAYOUT_SIZE_MASK;

     switch (screenLayout) {
      case Configuration.SCREENLAYOUT_SIZE_SMALL:
       row.setPadding(0, 7, 2, 7);   
       resized = Bitmap.createScaledBitmap(bitmap, 70, 70, true);
       txt.setTextSize(18);
     break;

      case Configuration.SCREENLAYOUT_SIZE_NORMAL:
       row.setPadding(0, 14, 2, 14);
       resized = Bitmap.createScaledBitmap(bitmap, 140, 140, true);
       txt.setTextSize(18);
      break;

      case Configuration.SCREENLAYOUT_SIZE_LARGE:
       row.setPadding(0, 14, 2, 14);
       resized = Bitmap.createScaledBitmap(bitmap, 200, 200, true);
       txt.setTextSize(24);
      break;

      case Configuration.SCREENLAYOUT_SIZE_XLARGE:
       row.setPadding(0, 14, 2, 14);
       resized = Bitmap.createScaledBitmap(bitmap, 200, 200, true);
       txt.setTextSize(24);
      break;

      default:

      break;
     }

     img.setImageBitmap(resized);
     txt.setGravity(Gravity.LEFT | Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
     txt.setLayoutParams(params);
     txt.setBackgroundColor(Color.WHITE);
     txt.setTypeface(null, Typeface.BOLD);
     txt.setTextColor(Color.BLACK);
     txt.setId(news_id);
     txt.setText(title_nohtml);
     txt.setClickable(true);

     row.addView(img);
     row.addView(txt);
     MainTable.addView(row);

     txt.setOnClickListener(new OnClickListener() {
      public void onClick(View v) {
       Intent intent = new Intent(MainActivity.this, NewsDetail.class);
       Bundle extras = new Bundle();
       extras.putInt("id_news", txt.getId());
       intent.putExtras(extras);
       startActivity(intent);
      }
     });
    }
   }catch (Exception e) {
     AlertDialog.Builder alertDialog = new AlertDialog.Builder(MainActivity.this);
     alertDialog.setTitle("Si è verificato un errore");
     alertDialog.setMessage("Errore 001" + "\n" + "Non è stato possibile soddisfare la tua richiesta, riprova più tardi.");
     alertDialog.show();
    }
    progress.dismiss();
    Looper.loop();
    Looper.getMainLooper().quitSafely();
    change();
   }

   @Override
    protected void onProgressUpdate(Void... values) {
     super.onProgressUpdate(values);
   }
  }
 /******************************************************************************************************/
 @Override
 public void onStart() {
  super.onStart();
  Tracker tracker = GoogleAnalytics.getInstance(this).getTracker("UA-49974758-1");
  tracker.set(Fields.SCREEN_NAME, "Visualizzazione prima pagina");
  tracker.send(MapBuilder.createAppView().set(Fields.customDimension(1), "Premium").build());
 }
 /******************************************************************************************************/
 public void change(){
  ChangeLog cl = new ChangeLog(this);
  if (cl.firstRun())
  cl.getLogDialog().show();
}
 /******************************************************************************************************/
 @Override
 public void onDestroy() {
  super.onDestroy();
  if ( progress!=null && progress.isShowing() ){
      progress.cancel();
  }
 }

/******************************************************************************************************/
 @Override
 public void onPause() {
  super.onPause();
  if ( progress!=null && progress.isShowing() ){
      progress.cancel();
  }
 }

***** РЕДАКТИРОВАТЬ *****

Код видеогалереи:

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
public class VideoGallery extends Activity {
 private ProgressDialog progress = null;


 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

  //Check if the connectivity is available   
  CheckConnectivity check = new CheckConnectivity();
  Boolean conn = check.checkNow(this.getApplicationContext());
  //if connectivity is available
  if(conn == true){
   //Create the action bar
   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {  
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);

    ActionBar actionBar = getActionBar();
    actionBar.setDisplayShowTitleEnabled(true);
    actionBar.setDisplayHomeAsUpEnabled(false);
    actionBar.setHomeButtonEnabled(false);
    actionBar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#0170a5")));
   }
   setContentView(R.layout.activity_main);
   GetVideo getVideo = new GetVideo();
   getVideo.execute();
  }else{
     connectivityMessage("Nessuna connessione presente, assicurati di avere il traffico dati oppure il Wi-Fi attivato e riprova."); 
  } 
 }
/************************************************************************/
 private class GetVideo extends AsyncTask<Void, Void, String>{

   @Override
   protected String doInBackground(Void... params) {
    Looper.prepare();  <---- LINE 86
    ReadServer read = new ReadServer();
    String result = read.readserver("id_gallery", "gall_video");
    return result;
   }

   @Override
   protected void onCancelled() {
    super.onCancelled();
   }

   @Override
   protected void onPreExecute() {
    progress = ProgressDialog.show(
    VideoGallery.this, null, "Caricamento video...");
    super.onPreExecute();
  }

    @Override
    protected void onPostExecute(String result) {
    super.onPostExecute(result);
    try{      
     TableLayout MainTable = (TableLayout)findViewById(R.id.main_table); 
     JSONArray Jobj = new JSONArray(result);
     String url_img = null;
     String url_video = null;

     for (int i = 0; i < Jobj.length(); i++){
      TableRow row = new TableRow(getApplicationContext()); 
      row.setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT));


      JSONObject list_video = Jobj.getJSONObject(i);
      Integer video_id = list_video.getInt("id_video");
      String video_title = list_video.getString("nome_video");
      String video_image = list_video.getString("video_img");
      String video_url = list_video.getString("url_video");

      Pattern p = Pattern.compile("^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]");
      Matcher m = p.matcher(video_image);

      Pattern v = Pattern.compile("^/video/[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]");
      Matcher vm = v.matcher(video_url);

      //Path video
      if(vm.matches() == false){
       url_video = path_youtube+video_url;
      }else if(vm.matches() == true){
       url_video = path_an_tv+video_url;
      }

      //Path image
      if(m.matches() == false){
       url_img = path+video_image;
      }else if(m.matches() == true){
       url_img = video_image;
      }

      final ImageView img = new ImageView(getApplicationContext());
      final TextView txt = new TextView(getApplicationContext());
      LayoutParams params;
      img.setAdjustViewBounds(true); 
      img.setScaleType(ImageView.ScaleType.CENTER_CROP);
      txt.setGravity(Gravity.LEFT | Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL );
      Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(url_img).getContent());
      Bitmap resized = null;

      int screenLayout = getApplicationContext().getResources().getConfiguration().screenLayout;
      screenLayout &= Configuration.SCREENLAYOUT_SIZE_MASK;

      switch (screenLayout) {
       case Configuration.SCREENLAYOUT_SIZE_SMALL:
        row.setPadding(0, 7, 0, 7);
        resized = Bitmap.createScaledBitmap(bitmap, 70, 70, true);
        params =  new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, 70);
        txt.setLayoutParams(params); 
        txt.setTextSize(18); 
      break;

       case Configuration.SCREENLAYOUT_SIZE_NORMAL:
        row.setPadding(0, 14, 0, 14);
        resized = Bitmap.createScaledBitmap(bitmap, 140, 140, true);
        params =  new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, 140);
        txt.setLayoutParams(params); 
        txt.setTextSize(18);  
      break;

       case Configuration.SCREENLAYOUT_SIZE_LARGE:
       row.setPadding(0, 14, 0, 14);
       resized = Bitmap.createScaledBitmap(bitmap, 200, 200, true);
       params =  new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, 200);
       txt.setLayoutParams(params);
       txt.setTextSize(24);
       break;

       case Configuration.SCREENLAYOUT_SIZE_XLARGE:
        row.setPadding(0, 14, 0, 14);
        resized = Bitmap.createScaledBitmap(bitmap, 200, 200, true); 
        params =  new TableRow.LayoutParams(LayoutParams.MATCH_PARENT, 200);
        txt.setLayoutParams(params);
        txt.setTextSize(24);
       break;

       default:

       break;
      }

      txt.setBackgroundColor(Color.WHITE);
      txt.setTypeface(null, Typeface.BOLD); 
      txt.setTextColor(Color.BLACK); 
      txt.setId(video_id); 
      txt.setTag(url_video); 
      txt.setText(video_title); 
      txt.setClickable(true);         
      img.setImageBitmap(resized);

      row.addView(img);
      row.addView(txt); 
      MainTable.addView(row);

      txt.setOnClickListener(new OnClickListener(){
       public void onClick(View v) {
        startActivity(new Intent(Intent.ACTION_VIEW,Uri.parse((String) txt.getTag())));
       }
      });
     }
    }catch(Exception e){
     AlertDialog.Builder alertDialog = new AlertDialog.Builder(VideoGallery.this);
     alertDialog.setTitle("Si è verificato un errore");
     alertDialog.setMessage("Errore 001" +"\n"+"Non è stato possibile soddisfare la tua richiesta, riprova più tardi.");
     alertDialog.show();        
    } 
    progress.dismiss();
    Looper.loop();
    Looper.getMainLooper().quitSafely();
   }

   @Override
    protected void onProgressUpdate(Void... values) {
     super.onProgressUpdate(values);
   }
  }

/******************************************************************************************************/
 @Override
 public void onStart() {
  super.onStart();
  Tracker tracker = GoogleAnalytics.getInstance(this).getTracker("UA-49974758-1");
  tracker.set(Fields.SCREEN_NAME, "Visualizzazione video");
  tracker.send(MapBuilder.createAppView().set(Fields.customDimension(1), "Premium").build());
 }

/******************************************************************************************************/
 @Override
 public void onDestroy() {
  super.onDestroy();
  if ( progress!=null && progress.isShowing() ){
      progress.cancel();
  }
 }

/******************************************************************************************************/
 @Override
 public void onPause() {
  super.onPause();
  if ( progress!=null && progress.isShowing() ){
      progress.cancel();
  }
 }

Когда я меняю активность на другую, которая снова содержит асинтаск, возникает ошибка:

11-14 11:49:18.196: E/AndroidRuntime(18749): FATAL EXCEPTION: AsyncTask #1
11-14 11:49:18.196: E/AndroidRuntime(18749): java.lang.RuntimeException: An error occured while executing doInBackground()
11-14 11:49:18.196: E/AndroidRuntime(18749):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
11-14 11:49:18.196: E/AndroidRuntime(18749):    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
11-14 11:49:18.196: E/AndroidRuntime(18749):    at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
11-14 11:49:18.196: E/AndroidRuntime(18749):    at java.util.concurrent.FutureTask.run(FutureTask.java:239)
11-14 11:49:18.196: E/AndroidRuntime(18749):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
11-14 11:49:18.196: E/AndroidRuntime(18749):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
11-14 11:49:18.196: E/AndroidRuntime(18749):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
11-14 11:49:18.196: E/AndroidRuntime(18749):    at java.lang.Thread.run(Thread.java:841)
11-14 11:49:18.196: E/AndroidRuntime(18749): Caused by: java.lang.RuntimeException: Only one Looper may be created per thread
11-14 11:49:18.196: E/AndroidRuntime(18749):    at android.os.Looper.prepare(Looper.java:78)
11-14 11:49:18.196: E/AndroidRuntime(18749):    at android.os.Looper.prepare(Looper.java:73)
11-14 11:49:18.196: E/AndroidRuntime(18749):    at com.miaapplicazione.VideoGallery$GetVideo.doInBackground(VideoGallery.java:86)
11-14 11:49:18.196: E/AndroidRuntime(18749):    at com.miaapplicazione.VideoGallery$GetVideo.doInBackground(VideoGallery.java:1)

**** РЕДАКТИРОВАТЬ 2 ****

Если я удалю Looper.prepare(); в видеогалерее произошла другая ошибка:

11-14 12:01:48.357: E/AndroidRuntime(20476): FATAL EXCEPTION: AsyncTask #2
11-14 12:01:48.357: E/AndroidRuntime(20476): java.lang.RuntimeException: An error occured while executing doInBackground()
11-14 12:01:48.357: E/AndroidRuntime(20476):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
11-14 12:01:48.357: E/AndroidRuntime(20476):    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
11-14 12:01:48.357: E/AndroidRuntime(20476):    at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
11-14 12:01:48.357: E/AndroidRuntime(20476):    at java.util.concurrent.FutureTask.run(FutureTask.java:239)
11-14 12:01:48.357: E/AndroidRuntime(20476):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
11-14 12:01:48.357: E/AndroidRuntime(20476):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
11-14 12:01:48.357: E/AndroidRuntime(20476):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
11-14 12:01:48.357: E/AndroidRuntime(20476):    at java.lang.Thread.run(Thread.java:841)
11-14 12:01:48.357: E/AndroidRuntime(20476): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
11-14 12:01:48.357: E/AndroidRuntime(20476):    at android.os.Handler.<init>(Handler.java:197)
11-14 12:01:48.357: E/AndroidRuntime(20476):    at android.os.Handler.<init>(Handler.java:111)
11-14 12:01:48.357: E/AndroidRuntime(20476):    at android.app.Activity.<init>(Activity.java:759)
11-14 12:01:48.357: E/AndroidRuntime(20476):    at com.alessandrianews.ReadServer.<init>(ReadServer.java:17)
11-14 12:01:48.357: E/AndroidRuntime(20476):    at com.alessandrianews.VideoGallery$GetVideo.doInBackground(VideoGallery.java:86)
11-14 12:01:48.357: E/AndroidRuntime(20476):    at com.alessandrianews.VideoGallery$GetVideo.doInBackground(VideoGallery.java:1)
11-14 12:01:48.357: E/AndroidRuntime(20476):    at android.os.AsyncTask$2.call(AsyncTask.java:287)
11-14 12:01:48.357: E/AndroidRuntime(20476):    at java.util.concurrent.FutureTask.run(FutureTask.java:234)
11-14 12:01:48.357: E/AndroidRuntime(20476):    ... 4 more

Как я могу решить эту проблему?? Я прочитал все остальные вопросы, но решения мне не помогают.


person Community    schedule 14.11.2014    source источник
comment
Можете ли вы сказать мне строку VideoGallery.java:86?   -  person SweetWisher ツ    schedule 14.11.2014
comment
Ошибка, ясно показывающая, что для одного потока может быть создан только один Looper, поэтому просто проверьте там.   -  person Pratik Dasa    schedule 14.11.2014
comment
@SweetWisherツ Код отредактирован... Я знаю, что может быть создан только один лупер, но если я удалю Looper.prepare(); мое приложение снова вылетает...   -  person    schedule 14.11.2014
comment
Проверьте это: stackoverflow.com/a/19356195/2591002   -  person SweetWisher ツ    schedule 14.11.2014
comment
Сомневаюсь, что вам нужен лупер. И кроме того, почему бы не рассказать нам, в чем ваша проблема...?   -  person ElDuderino    schedule 14.11.2014
comment
Я сомневаюсь, что вам действительно нужен лупер   -  person SweetWisher ツ    schedule 14.11.2014


Ответы (2)


Если вы хотите использовать AsyncTask, используйте его, вы не должны смешивать его с Lopper...

protected Integer doInBackground(Void... params) {}

уже работает над фоновым потоком и нет причин вызывать Lopper, зачем?

Если вашему приложению необходимо выполнять какие-то длительные вычисления, то AsyncTask является очень хорошим инструментом для этого, потому что предлагает методы, которые работают с потоком пользовательского интерфейса и позволяют обновлять пользовательский интерфейс с некоторым ходом работы, потому что каждый пользователь, который будет использовать ваше приложение, должен знать это приложение " делать что-то" (когда это занимает более 2-5 секунд).

Кроме того, это общий и дает некоторые преимущества.

Если вам не нужно обновлять пользовательский интерфейс, просто используйте, например, Handler.

так что удали Looper.prepare();

person Akash Moradiya    schedule 14.11.2014
comment
Я действительно сбит с толку, потому что я понимаю ваши примеры, но я не понимаю, что я должен делать. Если я хочу решить свою проблему, я должен удалить Looper.prepare(); из моего кода, но если я удалю ошибку, возникнет ошибка, потому что Looper.prepare(); нет в моем коде... То, что я должен сделать, простое: во время загрузки (в фоновом режиме) я хочу отображать простой индикатор выполнения, когда загрузка завершена, я хочу отменить прогресс и отображать данные. Когда я меняю активность, вызывается другая асинтаск, и история такая же !!! - person ; 14.11.2014

Попробуйте добавить:

if (Looper.myLooper() == null) Looper.prepare;

Это сработало для меня

person Community    schedule 17.11.2014