在Android中下载背景图像需要帮助



我有一个图像视图,我已经写了刷屏,在刷屏的时候,图像是从互联网下载的,所以我认为我必须在刷屏之前在后台下载图像,对于那些我需要使用asynctask或Service或IntentService的图像,所有这些都将有助于下载和存储在data/data/mypackages中,但在我的情况下,刷屏仍然很慢,还告诉我哪一个是最好的,是不是我打电话给的方式正确

1.异步任务

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();
            }
        }
    }

此处显示我的服务

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());
        }
    }
}

从MyActivity 调用IntentService

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);

      }
    }

使用服务下载它的最佳方式,就像我从服务器下载文件并放入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());
    }

对于稍后遇到此问题的人,请查看项目com.example.android.bitmapfun.ui.ImageGridActivity的android示例代码中使用的异步下载机制。它异步下载图像,还缓存图像以便在ImageView中脱机显示。人们已经将他们的代码封装在这个之上,并制作了自己的图像加载库。这些库使用AsyncTask而不是服务。异步任务预计将在几秒钟内完成工作。

如果你想下载更大的东西,我建议你使用自API 9以来可用的DownloadManager,而不是使用服务。其中有很多代码为下载增加了弹性。

下载管理器是一种处理长时间运行的HTTP下载的系统服务。客户端可以请求将URI下载到特定的目的地文件。下载管理器将在后台进行下载,负责HTTP交互,并在故障后或连接更改和系统重新启动时重试下载。此类的实例应通过传递DOWNLOAD_SERVICE通过getSystemService(String)获得。通过此API请求下载的应用程序应为ACTION_NOTIFICATION_LICKED注册广播接收器,以便在用户在通知中或从下载UI中单击正在运行的下载时进行适当处理。请注意,应用程序必须具有INTERNET权限才能使用此类。

您可能对此进行了过度设计。我已经实现了动态加载图像的滑动,我只使用了一个简单的实用程序类,它通过静态方法调用为我完成了所有操作。试试这个类:

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);

就是这样。
如果您有来自JSON对象的URL,请将该URL解析为字符串,以便:
String url = jsonObj.getString("url");然后调用fetchDrawableOnThread(url, yourImageViewReference);

使用凌空抽射。使用截击网络图像视图,您可以执行

我们在这里使用最新的架构组件。我们为一些代表下载状态的标志制作了一些实时数据的观察者。在服务中,我们下载图像并完成更新实时数据,以便观察员方法自动调用

最新更新