Android - 如何在后台进程中下载大量图像(大量 http url)
Android - How to download a large nos of images (large nos of http url) in Background Process
我从服务器获取图像列表 url,其数量大约在 400-500 之间。如何在后台将此图片下载到设备的本地文件夹中?
到目前为止,我有 运行 一个前台服务,我在其中使用 ExecutorService 来 运行 一个线程。我的服务代码如下
public class SaveImageService extends Service {
private Context context;
public static final String NOTIFICATION_CHANNEL_ID = "10001";
public SaveImageService() {
}
@Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startMyOwnForeground();
else
startForeground(1, new Notification());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
context = this;
super.onStartCommand(intent, flags, startId);
List<Callable<String>> saveDataThreads = new ArrayList<>();
SaveTaskImage saveTaskImage = new SaveTaskImage(this);
saveDataThreads.add(saveTaskImage);
ExecutorService executor = Executors.newFixedThreadPool(saveDataThreads.size());
try {
List<Future<String>> aaa = executor.invokeAll(saveDataThreads);
} catch (InterruptedException e) {
e.printStackTrace();
}
executor.shutdown();
if (executor.isShutdown()) {
stopForeground(true);
stopSelf();
}
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void startMyOwnForeground() {
String NOTIFICATION_CHANNEL_ID = "com.example.simpleapp";
String channelName = "My Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.mipmap.talentify_logo_red)
.setContentTitle("App is running in background")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
}
}
在 SaveTask 线程中,我触发了如下同步任务
new SaveImageAsync ("file_path").executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,url);
下面是我的异步任务代码:
public class SaveImageAsync extends AsyncTask<String, Void, String> {
private MediaSaver mediaSaver;
public SaveImageAsync(MediaSaver mediaSaver){
this.mediaSaver = mediaSaver;
}
@Override
protected String doInBackground(String... params) {
Bitmap bmp = null;
try{
System.out.println("Save image url --> "+params[0].replaceAll(" ", "%20"));
URL url = new URL(params[0].replaceAll(" ", "%20"));
InputStream fileInputStream = url.openStream();
if(fileInputStream != null) {
mediaSaver.save(fileInputStream);
System.out.println("Saving image --> ");
}else{
System.out.println("Not Saving image --> ");
}
}catch (Exception e){
e.printStackTrace();
}
return "";
}
@Override
protected void onPostExecute(String string) {
}
}
但在这种方法中,我只能在背景中保存 50 -60 张图像。它不会 运行 宁到结束。我该怎么办请建议
使用下面的库 -
implementation 'com.amitshekhar.android:android-networking:1.0.2'
该库的实现 -
for (int j = 0; j < imageArrayList.size(); j++) {
downloadImage(imageArrayList.getImagePath(j), imageArrayList.get(j),getImageName);
}
private void downloadImage(String imageURL, String imagename) {
AndroidNetworking.download(imageURL, getCacheDir().getPath() + "/" + Constant.FOLDER_NAME + "/", imagename)
.setPriority(Priority.HIGH)
.build()
.setDownloadProgressListener(new DownloadProgressListener() {
@Override
public void onProgress(long bytesDownloaded, long totalBytes) {
// do anything with progress
}
})
.startDownload(new DownloadListener() {
@Override
public void onDownloadComplete() {
// do anything after completion
}
@Override
public void onError(ANError error) {
// handle error
}
});
}
您也可以使用 android 下载管理器 API。
Android: How to use download manager class?
我从服务器获取图像列表 url,其数量大约在 400-500 之间。如何在后台将此图片下载到设备的本地文件夹中?
到目前为止,我有 运行 一个前台服务,我在其中使用 ExecutorService 来 运行 一个线程。我的服务代码如下
public class SaveImageService extends Service {
private Context context;
public static final String NOTIFICATION_CHANNEL_ID = "10001";
public SaveImageService() {
}
@Override
public void onCreate() {
super.onCreate();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
startMyOwnForeground();
else
startForeground(1, new Notification());
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
context = this;
super.onStartCommand(intent, flags, startId);
List<Callable<String>> saveDataThreads = new ArrayList<>();
SaveTaskImage saveTaskImage = new SaveTaskImage(this);
saveDataThreads.add(saveTaskImage);
ExecutorService executor = Executors.newFixedThreadPool(saveDataThreads.size());
try {
List<Future<String>> aaa = executor.invokeAll(saveDataThreads);
} catch (InterruptedException e) {
e.printStackTrace();
}
executor.shutdown();
if (executor.isShutdown()) {
stopForeground(true);
stopSelf();
}
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void startMyOwnForeground() {
String NOTIFICATION_CHANNEL_ID = "com.example.simpleapp";
String channelName = "My Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.mipmap.talentify_logo_red)
.setContentTitle("App is running in background")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
startForeground(2, notification);
}
}
在 SaveTask 线程中,我触发了如下同步任务
new SaveImageAsync ("file_path").executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,url);
下面是我的异步任务代码:
public class SaveImageAsync extends AsyncTask<String, Void, String> {
private MediaSaver mediaSaver;
public SaveImageAsync(MediaSaver mediaSaver){
this.mediaSaver = mediaSaver;
}
@Override
protected String doInBackground(String... params) {
Bitmap bmp = null;
try{
System.out.println("Save image url --> "+params[0].replaceAll(" ", "%20"));
URL url = new URL(params[0].replaceAll(" ", "%20"));
InputStream fileInputStream = url.openStream();
if(fileInputStream != null) {
mediaSaver.save(fileInputStream);
System.out.println("Saving image --> ");
}else{
System.out.println("Not Saving image --> ");
}
}catch (Exception e){
e.printStackTrace();
}
return "";
}
@Override
protected void onPostExecute(String string) {
}
}
但在这种方法中,我只能在背景中保存 50 -60 张图像。它不会 运行 宁到结束。我该怎么办请建议
使用下面的库 -
implementation 'com.amitshekhar.android:android-networking:1.0.2'
该库的实现 -
for (int j = 0; j < imageArrayList.size(); j++) {
downloadImage(imageArrayList.getImagePath(j), imageArrayList.get(j),getImageName);
}
private void downloadImage(String imageURL, String imagename) {
AndroidNetworking.download(imageURL, getCacheDir().getPath() + "/" + Constant.FOLDER_NAME + "/", imagename)
.setPriority(Priority.HIGH)
.build()
.setDownloadProgressListener(new DownloadProgressListener() {
@Override
public void onProgress(long bytesDownloaded, long totalBytes) {
// do anything with progress
}
})
.startDownload(new DownloadListener() {
@Override
public void onDownloadComplete() {
// do anything after completion
}
@Override
public void onError(ANError error) {
// handle error
}
});
}
您也可以使用 android 下载管理器 API。 Android: How to use download manager class?