Нужна помощь в загрузке фоновых изображений в Android? - PullRequest
14 голосов
/ 10 июня 2011

У меня есть просмотр изображений, я написал смахивание, во время смахивания изображения загружаются из Интернета, поэтому я подумал, что мне нужно загрузить изображения в фоновом режиме, прежде чем смахивать, для чего мне нужно использовать asynctaskили Service или IntentService, все это поможет в загрузке и хранении в data / data / mypackages, но в моем случае все еще происходит медленное перелистывание любой идеи, также дайте мне понять, какая из них лучшая, правильно ли я звоню

1.asynctask

2.услуги

3.Служба намерений , как показано ниже,

Я запуталась, какой метод правильный, потому что моя проблема все еще не решена

Вот пример кода асинхронной задачи

public class Demo extends Activity {

  @Override

  public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

       new FirstTask().execute(); // calling Asynctask here

  }

} ​​

Асинхронный код задачи

private class FirstTask extends AsyncTask<Void, Void, Void> {
        private final ProgressDialog dialog = new ProgressDialog(Catalogue.this);
        int temp = 0;

        // can use UI thread here
        protected void onPreExecute() {
            this.dialog.setMessage("Loading...");
            this.dialog.setCancelable(false);
            //this.dialog.show();
            System.gc();
            Toast.makeText(Catalogue.this, "My Async  Created",
                    Toast.LENGTH_LONG).show();
        }

        @Override
        protected Void doInBackground(Void... params) {
            Looper.prepare();  
            try {

                myddownloadmethod();// calling my download method

            } catch (Exception e) {
                Util.trace("Error in Async"+e.getMessage());

            }
              Looper.loop();

            return null;
        }

        protected void onPostExecute(Void result) {

            if (this.dialog.isShowing()) {
                Toast.makeText(Catalogue.this, "My Async destroyed",
                        Toast.LENGTH_LONG).show();
                Toast.makeText(Catalogue.this, "count" + temp,
                        Toast.LENGTH_LONG).show();
                this.dialog.dismiss();
            }
        }
    }

Вот мой сервис sinppet

public class MyService extends Service implements Runnable

{      @Override

        public void onCreate() {

                super.onCreate();

                Thread mythread = new Thread(this);

                mythread.start();

        }



        public void run() {

                Looper.prepare();  

                try {

                        myddownloadmethod();// calling my download method

                } catch (Exception e1) {

                        // TODO Auto-generated catch block

                        e1.printStackTrace();

                }

                Looper.loop();

        }



        @Override
        public IBinder onBind(Intent intent) {

                // TODO Auto-generated method stub

                return null;

        }



}



Invoking Service  

public class ServicesDemo extends Activity {    

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

      startService(new Intent(this, MyService.class));


  }

}

Вот код IntentService

public class Downloader extends IntentService {

    public Downloader() {
        super("Downloader");
    }

    @Override
    public void onCreate() {
        super.onCreate();


    }

    @Override
    public void onDestroy() {
        super.onDestroy();

            }

    @Override   
    public void onHandleIntent(Intent i) {

        try {
             myddownloadmethod();// calling my download method
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            Log.d("Error",e1.getMessage());
        }

    }
}

Вызов IntentService из MyActivity

public class ServicesDemo extends Activity {    
      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Intent i1=new Intent(this, Downloader.class);
        startService(i1);



      }

    }

Ответы [ 5 ]

16 голосов
/ 13 июня 2011

Лучший способ загрузить его с помощью сервиса, как я сделал, чтобы загрузить файл с сервера и вставить в SD-карту, также использовать уведомление для него.Это довольно длинный код, но я думаю, что идеальный, если ничего не понял, тогда, пожалуйста, зайдите в блог разработчика Android для сервисов.

public class DownloadService extends Service{

     SharedPreferences preferences;

    private static final String DOCUMENT_VIEW_STATE_PREFERENCES = "DjvuDocumentViewState";

      private Looper mServiceLooper;
      private ServiceHandler mServiceHandler;
      private NotificationManager mNM;
      String downloadUrl;
      public static boolean serviceState=false;

      // Handler that receives messages from the thread
      private final class ServiceHandler extends Handler {
          public ServiceHandler(Looper looper) {
              super(looper);
          }
          @Override
          public void handleMessage(Message msg) {
              downloadFile();
              showNotification(getResources().getString(R.string.notification_catalog_downloaded),"VVS");
              stopSelf(msg.arg1);
          }
      }


    @Override
        public void onCreate() {
            serviceState=true;
            mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
            HandlerThread thread = new HandlerThread("ServiceStartArguments",1);
            thread.start();

            // Get the HandlerThread's Looper and use it for our Handler 
            mServiceLooper = thread.getLooper();
            mServiceHandler = new ServiceHandler(mServiceLooper);

        }



     @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
             Log.d("SERVICE-ONCOMMAND","onStartCommand");  

               Bundle extra = intent.getExtras();
               if(extra != null){
                   String downloadUrl = extra.getString("downloadUrl");
                   Log.d("URL",downloadUrl);

                   this.downloadUrl=downloadUrl;
               }

              Message msg = mServiceHandler.obtainMessage();
              msg.arg1 = startId;
              mServiceHandler.sendMessage(msg);

              // If we get killed, after returning from here, restart
              return START_STICKY;
          }



     @Override
          public void onDestroy() {

             Log.d("SERVICE-DESTROY","DESTORY");
             serviceState=false;
            //Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show(); 
          }


     @Override
      public IBinder onBind(Intent intent) {
          // We don't provide binding, so return null
          return null;
      }


      public void downloadFile(){

            downloadFile(this.downloadUrl,fileName);


      }



        void showNotification(String message,String title) {
        // In this sample, we'll use the same text for the ticker and the expanded notification
        CharSequence text = message;

        // Set the icon, scrolling text and timestamp
       Notification notification = new Notification(R.drawable.icon, "vvs",
                System.currentTimeMillis());
        notification.flags |= Notification.FLAG_AUTO_CANCEL;
        Intent intent = new Intent(this, HomeScreenActivity.class);
        intent.setFlags (Intent.FLAG_ACTIVITY_CLEAR_TOP);
         //The PendingIntent to launch our activity if the user selects this notification
        PendingIntent contentIntent = PendingIntent.getActivity(this.getBaseContext(), 0,
              intent, PendingIntent.FLAG_CANCEL_CURRENT);

        // Set the info for the views that show in the notification panel.
        notification.setLatestEventInfo(this, title,
                      text, contentIntent);
        // Send the notification.
        // We use a layout id because it is a unique number.  We use it later to cancel.
        mNM.notify(R.string.app_name, notification);
    }

  public void downloadFile(String fileURL, String fileName) {

    StatFs stat_fs = new StatFs(Environment.getExternalStorageDirectory().getPath());
    double avail_sd_space = (double)stat_fs.getAvailableBlocks() *(double)stat_fs.getBlockSize();
    //double GB_Available = (avail_sd_space / 1073741824);
    double MB_Available = (avail_sd_space / 10485783);
    //System.out.println("Available MB : " + MB_Available);
    Log.d("MB",""+MB_Available);
   try {
        File root =new File(Environment.getExternalStorageDirectory()+"/vvveksperten");
        if(root.exists() && root.isDirectory()) {

        }else{
            root.mkdir();
        }
        Log.d("CURRENT PATH",root.getPath());
        URL u = new URL(fileURL);
        HttpURLConnection c = (HttpURLConnection) u.openConnection();
        c.setRequestMethod("GET");
        c.setDoOutput(true);
        c.connect();
          int fileSize  = c.getContentLength()/1048576;
          Log.d("FILESIZE",""+fileSize);
          if(MB_Available <= fileSize ){
               this.showNotification(getResources().getString(R.string.notification_no_memory),getResources().getString(R.string.notification_error));
              c.disconnect();
              return;
          } 

        FileOutputStream f = new FileOutputStream(new File(root.getPath(), fileName));

        InputStream in = c.getInputStream();


        byte[] buffer = new byte[1024];
        int len1 = 0;
        while ((len1 = in.read(buffer)) > 0) {
            f.write(buffer, 0, len1);
        }
        f.close();
        File file = new File(root.getAbsolutePath() + "/" + "some.pdf");
        if(file.exists()){
            file.delete();
            Log.d("FILE-DELETE","YES");
        }else{
            Log.d("FILE-DELETE","NO");
        }
        File from =new File(root.getAbsolutePath() + "/" + fileName);
        File to = new File(root.getAbsolutePath() + "/" + "some.pdf");


        } catch (Exception e) {
        Log.d("Downloader", e.getMessage());

    }
3 голосов
/ 26 марта 2013

Для тех, кто сталкивается с этим вопросом позже, взгляните на механизм асинхронной загрузки, используемый в примере кода Android для проекта com.example.android.bitmapfun.ui.ImageGridActivity.Он загружает изображения асинхронно, а также кэширует их для автономного отображения в ImageView.Люди обернули свой код вокруг этого и сделали библиотеки загрузки изображений своих .Эти библиотеки используют AsyncTask вместо службы.Ожидается, что асинхронные задачи завершат свою работу в течение нескольких секунд.

Если вы хотите скачать что-то большее, я бы порекомендовал DownloadManager , который доступен с API 9 вместопользуясь услугами.Там много кода, который повышает устойчивость загрузки.

Менеджер загрузок - это системная служба, которая обрабатывает длительные загрузки HTTP.Клиенты могут запросить загрузку URI в конкретный файл назначения.Менеджер загрузок будет выполнять загрузку в фоновом режиме, заботясь о HTTP-взаимодействиях и повторяя попытки загрузки после сбоев или при изменениях подключения и перезагрузках системы.Экземпляры этого класса должны быть получены через getSystemService (String) путем передачи DOWNLOAD_SERVICE.Приложения, запрашивающие загрузки через этот API, должны зарегистрировать получателя широковещательной рассылки для ACTION_NOTIFICATION_CLICKED, чтобы соответствующим образом обрабатывать, когда пользователь нажимает на текущую загрузку в уведомлении или в пользовательском интерфейсе загрузок.Обратите внимание, что для использования этого класса приложение должно иметь разрешение ИНТЕРНЕТ.

2 голосов
/ 10 июня 2011

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

package com.beget.consumer.util;

/*
 Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.    
*/
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.ImageView;

public class DrawableLoader {
    private final Map<String, Drawable> drawableMap;
    private WeakReference<ImageView> imageViewReference;

    public DrawableLoader() {
        drawableMap = new HashMap<String, Drawable>();
    }

    public Drawable fetchDrawable(String urlString) {
        if (drawableMap.containsKey(urlString)) {
            return drawableMap.get(urlString);
        }

        Log.d(this.getClass().getSimpleName(), "image url:" + urlString);
        try {
            InputStream is = fetch(urlString);
            Drawable drawable = Drawable.createFromStream(is, "src");
            drawableMap.put(urlString, drawable);
            Log.d(this.getClass().getSimpleName(), "got a thumbnail drawable: " + drawable.getBounds() + ", "
                    + drawable.getIntrinsicHeight() + "," + drawable.getIntrinsicWidth() + ", "
                    + drawable.getMinimumHeight() + "," + drawable.getMinimumWidth());
            return drawable;
        } catch (MalformedURLException e) {
            Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
            return null;
        } catch (IOException e) {
            Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
            return null;
        }
    }

    public void fetchDrawableOnThread(final String urlString, final ImageView imageView) {

        imageViewReference = new WeakReference<ImageView>(imageView);

        if (drawableMap.containsKey(urlString)) {
            imageViewReference.get().setImageDrawable(drawableMap.get(urlString));
        }

        final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message message) {
                imageViewReference.get().setImageDrawable((Drawable) message.obj);
            }
        };

        Thread thread = new Thread() {
            @Override
            public void run() {
                //TODO : set imageView to a "pending" image
                Drawable drawable = fetchDrawable(urlString);
                Message message = handler.obtainMessage(1, drawable);
                handler.sendMessage(message);
            }
        };
        thread.start();
    }

    private InputStream fetch(String urlString) throws MalformedURLException, IOException {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet request = new HttpGet(urlString);
        HttpResponse response = httpClient.execute(request);
        return response.getEntity().getContent();
    }

}

Это все, что вам нужно. Затем, когда вам нужно загрузить изображение, вы звоните:

fetchDrawableOnThread("http://path/to/your/image.jpg", yourImageViewReference);

Вот и все.
Если у вас есть URL-адрес из объекта JSON, проанализируйте URL-адрес в вашей строке так:
String url = jsonObj.getString("url"); Затем позвоните fetchDrawableOnThread(url, yourImageViewReference);

0 голосов
/ 11 августа 2018

здесь мы используем самые последние компоненты architecure. Мы создаем некоторых наблюдателей с живыми данными для некоторого флага, который представляет статус загрузки. В сервисе мы загружаем изображение и, завершая, обновляем данные в реальном времени, чтобы метод наблюдателей автоматически вызывал

0 голосов
/ 03 августа 2018

Используйте залп.Используя вид сетевого изображения залпа, вы можете сделать это

...