Проблемы с обработчиком для получения изображения из сети в фоновом режиме - PullRequest
0 голосов
/ 25 января 2012

Я пытаюсь получить изображение из Интернета, используя поток, и я использую обработчик для отображения изображения в пользовательском интерфейсе, как только изображение закончило загрузку.Он отлично работает на Nexus S с ICS, но при использовании Samsung под управлением Android 2.1 изображение никогда не отображается на экране!

Более того, странно то, что когда я выполняю пошаговую отладку с помощьюточка останова внутри потока, где изображение извлекается из Интернета, код работает нормально, и изображение отображается, но когда я ставлю точку останова дальше вниз, за ​​пределы потока, где находится код для обновления пользовательского интерфейса, изображение делаетне отображается, как если бы этот код никогда не был достигнут.Вот мой код:

private Handler handler;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_activity);
    formatter.setMinimumFractionDigits(2);
    formatter.setMaximumFractionDigits(2);
    handler = new Handler();
    ...

Функция, которая запускает извлечение изображения с помощью рабочего потока:

private void retrieveImage() {
    DeviceInfo dv = new DeviceInfo(this);
    String uri = MerchantProAPI.GET_CLIENT_IMAGE_URL;
    uri += "?api_id=" + MerchantProAPI.API_ID;
    uri += "&merchantphone=" + dv.getPhoneNumber();
    uri += "&imei=" + dv.getDeviceId();
    uri += "&customerid=" + customerno;
    Thread thr = new Thread(null, new RetrieveImageWorker(uri), "RetrieveImage");
    thr.start();
}

RetrieveImageWorker - это закрытый класс в деятельности, и я используюОбработчик, инициализированный в методе onCreate для публикации и обновления изображения с новым загруженным изображением:

private class RetrieveImageWorker implements Runnable {
    String uri;
    Bitmap bm;

    public RetrieveImageWorker(String uri) {
        this.uri = uri;
    }

    @Override
    public void run() {
        HttpClient client = new DefaultHttpClient();
        HttpGet request = new HttpGet(uri);
        try {
            HttpResponse response = client.execute(request);
            HttpEntity entity = response.getEntity();
            String contentType = entity.getContentType().getValue();
            DisplayMetrics metrics = new DisplayMetrics();
            getWindowManager().getDefaultDisplay().getMetrics(metrics);
            int halfScreen = metrics.widthPixels / 2;
            int photoWidth = halfScreen > 200 ? 200 : halfScreen;
            if (contentType.contains("image/jpeg") || contentType.contains("image/png") || contentType.contains("image/gif")) {
                bm = BitmapFactory.decodeStream(entity.getContent());
                if (bm.getWidth() > photoWidth)
                bm = Bitmap.createScaledBitmap(bm, photoWidth, Math.round((photoWidth*bm.getHeight())/bm.getWidth()), false);
            }
            handler.post(new NotifierImage(bm));
        } catch (Exception e) {
            handler.post(new Notifier(e.getMessage()));
        }
    }

}

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

private class NotifierImage implements Runnable {
    private Bitmap bm;

    public NotifierImage(Bitmap bm) {
        this.bm = bm;
    }

    @Override
    public void run() {
        if (this.bm != null) {
            updateDisplayPhoto(bm);
        }
    }

}

updateDisplayPhoto просто обновляет вид изображения пользовательского интерфейса:

private void updateDisplayPhoto(Bitmap photo) {
    imageView.setImageBitmap(photo);
}

Все эти элементы являются частью одной и той же операции.Как я уже говорил, на Nexus S с ICS он работает нормально, но на Samsung с Android 2.1-update изображение никогда не обновляется в пользовательском интерфейсе.Что я сделал не так?

1 Ответ

0 голосов
/ 25 января 2012

Просто Просто используйте AsyncTask. Поместите свой код для получения изображения в doInBackground() и установите для ImageView в вашем PostExecute(). Зачем использовать Runnable и Thread, если Android предоставляет хороший и понятный способ.

private class MyAsyncTask extends AsyncTask<Void, Void, Void>
    {
            @Override
        protected void onPreExecute() {
            mProgressDialog = ProgressDialog.show(ActivityName.this, "Loading...", "Data is Loading...");
        }

        @Override
        protected Void doInBackground(Void... params) {
           // your network operation
            return null;
        }
        ProgressDialog mProgressDialog;
        @Override
        protected void onPostExecute(Void result) {
            mProgressDialog.dismiss();
        }
    }
...