2015-05-15 5 views
1

Я использую поток, чтобы установить изображение в качестве фона, и в этой теме у меня есть диалог. Диалог начинается и должен быть закрыт, когда будут установлены обои. Это код до сих порCalculate time thread android

setWallbtn.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       final ProgressDialog myPd_ring=ProgressDialog.show(SingleWall.this, "Setting wallpaper", "", true); 
       new Handler().postDelayed(new Runnable() { 
         @Override 
         public void run() { 
          // TODO Auto-generated method stub 
          WallpaperManager wallManager = WallpaperManager.getInstance(getApplicationContext()); 
          try { 
           image = BitmapFactory.decodeStream(url.openConnection().getInputStream()); 
           wallManager.setBitmap(image); 
           Toast.makeText(SingleWall.this, "Wallpaper Set Successfully!!", Toast.LENGTH_SHORT).show(); 
           myPd_ring.dismiss(); 
          } catch (IOException e) { 
           // TODO Auto-generated catch block 
           e.printStackTrace(); 
           Toast.makeText(SingleWall.this, "Setting WallPaper Failed!!", Toast.LENGTH_SHORT).show(); 
           myPd_ring.dismiss(); 
          } 
         } 
        }, 4000); 


      } 
     }); 

Так, по нажатию на кнопку запускает поток и в течение 4 секунд диалог должен быть виден со значком прогресса. Но это неверно! время установки фона может быть больше или меньше 4 секунд! Таким образом, 4000 должен рассчитываться в основании времени, чтобы установить изображение в качестве обоев. Является ли это возможным?

пс. Я не могу использовать AsyncTask, потому что я получаю много NullPointerExceptions

ответ

1

Обратите внимание, что вы не используете отдельную тему с кодом в вашем вопросе, вы работаете a Runnable на основной поток пользовательского интерфейса.

Если посмотреть на the documentation, рекомендуется использовать AsyncTask для декодирования растровых изображений, и это также лучший способ для достижения желаемого результата, где ProgressDialog освобождается только после завершения процесса, который может принимать непредсказуемый количество времени.

Вам просто нужно поместить код в это правильное место, и дать ему то, что ему нужно через varargs проходил в

Вот как вы должны начать AsyncTask:.

setWallbtn.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      new LoadImage().execute(url); 
     } 
    }); 

Тогда, создайте AsyncTask как подкласс класса SingleWall. Введите сетевой код в doInBackground(), который будет загружать и декодировать растровое изображение, а затем помещать код, связанный с UI, в onPostExecute(), который работает в потоке пользовательского интерфейса.

Обратите внимание, что вы можете также использовать WeakReference к экземпляру WallpaperManager, как описано в приведенной выше ссылке, но я буду держать его просто здесь и просто получить доступ к wallManager напрямую, что вы можете сделать, если AsyncTask является подклассом вашей деятельности.

class LoadImage extends AsyncTask<URL, Void, Bitmap> { 

    ProgressDialog myPd_ring; 

    @Override 
    protected void onPreExecute() { 
     //Start Progress Dialog here 
     myPd_ring = ProgressDialog.show(SingleWall.this, "Setting wallpaper", "", true); 
    } 

    //Runs in a background Thread 
    @Override 
    protected Bitmap doInBackground(URL... params) { 
     URL url = params[0]; 
     Bitmap image = null; 
     try { 
      image = BitmapFactory.decodeStream(url.openConnection().getInputStream()); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return image; 
    } 

    //Runs on the UI Thread 
    @Override 
    protected void onPostExecute(Bitmap image) { 
     myPd_ring.dismiss(); 

     if (image == null){ 
      Toast.makeText(SingleWall.this, "Setting WallPaper Failed!!", Toast.LENGTH_LONG).show(); 
     } 
     else{ 
      //set image here 
      try { 
       SingleWall.this.wallManager.setBitmap(image); 

       Toast.makeText(SingleWall.this, "Wallpaper Set Successfully!!", Toast.LENGTH_SHORT).show(); 

      } catch (IOException e) { 
       e.printStackTrace(); 
       Toast.makeText(SingleWall.this, "Setting WallPaper Failed!!", Toast.LENGTH_LONG).show(); 
      } 

     } 
    } 
} 
+0

Wow nice it works хорошо спасибо !! –

+1

@ End.Game Нет проблем! Рад, что он работает на вас! –

+0

@ End.Game Я только что понял, что у меня был успех тоста в неправильном месте, был шанс на неудачу и успех Тост. Просто обновил ответ с небольшим исправлением. –

0

Использование AsyncTask, вероятно, появятся нулевые указатели, потому что вы пытаетесь обновить интерфейс во время обработки задачи. Вы, возможно, придется использовать что-то вроде этого внутри AsyncTask:

activity.runOnUiThread(new Runnable() { 
     public void run() { 
      activity.doSomeSpecialUIWork(); 
     } 
    }); 
} 

Надежда, которая работает - вот что решил это для меня, когда я получаю странные нулевые указатели во время AsyncTask.

Вот пример из другого поста: how to use runOnUiThread

Для вашего конкретного кода, может быть, это:

setWallbtn.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       activity.runOnUiThread(new Runnable() { 
         public void run() { 
          final ProgressDialog myPd_ring=ProgressDialog.show(SingleWall.this, "Setting wallpaper", "", true); 
          // TODO Auto-generated method stub 
          WallpaperManager wallManager = WallpaperManager.getInstance(getApplicationContext()); 
          try { 
           image = BitmapFactory.decodeStream(url.openConnection().getInputStream()); 
           wallManager.setBitmap(image); 
           Toast.makeText(SingleWall.this, "Wallpaper Set Successfully!!", Toast.LENGTH_SHORT).show(); 
           myPd_ring.dismiss(); 
          } catch (IOException e) { 
           // TODO Auto-generated catch block 
           e.printStackTrace(); 
           Toast.makeText(SingleWall.this, "Setting WallPaper Failed!!", Toast.LENGTH_SHORT).show(); 
           myPd_ring.dismiss(); 
          } 
         } 
        }); 
       } 
      } 
     });