Нужна помощь в загрузке фоновых изображений в 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());
}
}
}
Вызов 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 ответов
Лучший способ загрузить его с помощью сервиса, как я сделал, чтобы загрузить файл с сервера и вставить в 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());
}
Для тех, кто сталкивается с этим вопросом позже, взгляните на механизм асинхронной загрузки, используемый в примере кода Android для проекта. com.example.android.bitmapfun.ui.ImageGridActivity
, Он загружает изображения асинхронно, а также кэширует их для автономного отображения в ImageView. Люди обернули свой код вокруг этого и сделали собственные библиотеки загрузки изображений. Эти библиотеки используют AsyncTask вместо службы. Ожидается, что асинхронные задачи завершат свою работу в течение нескольких секунд.
Если вы хотите скачать что-то большее, я бы порекомендовал DownloadManager, который доступен с API 9, вместо использования сервисов. Там много кода, который добавляет устойчивость к загрузке.
Менеджер загрузок - это системная служба, которая обрабатывает длительные загрузки HTTP. Клиенты могут запросить загрузку URI в конкретный файл назначения. Менеджер загрузок будет выполнять загрузку в фоновом режиме, заботясь о HTTP-взаимодействиях и повторяя попытки загрузки после сбоев или при изменении подключения и перезагрузках системы. Экземпляры этого класса должны быть получены через getSystemService(String), передав DOWNLOAD_SERVICE. Приложения, запрашивающие загрузки через этот API, должны зарегистрировать приемник широковещательной рассылки для ACTION_NOTIFICATION_CLICKED, чтобы соответствующим образом обрабатывать, когда пользователь нажимает на текущую загрузку в уведомлении или в пользовательском интерфейсе загрузок. Обратите внимание, что приложение должно иметь разрешение 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);
Вот и все.
Если у вас есть URL-адрес из объекта JSON, проанализируйте URL-адрес в вашей строке так:String url = jsonObj.getString("url");
Тогда позвони fetchDrawableOnThread(url, yourImageViewReference);
Здесь мы используем самые последние компоненты architecure. Мы создаем некоторых наблюдателей с живыми данными для некоторого флага, который представляет состояние загрузки. В сервисе мы загружаем изображение, и в завершение мы обновляем действующие данные, чтобы метод наблюдателей автоматически вызывался
Используйте залп. Используя вид изображения сети залпов, вы можете сделать это