使用android服务下载大文件的正确方法
我为开始下载大文件创建了一个服务。我决定创建一个ThreadPoolExecutor,因为在我的应用程序中,它可以一次下载多个文件。在每个线程中,我添加一个我从活动中发送的名称。如果用户决定停止一个特定的download,我会使用它,这样就可以停止特定的线程 代码可以工作,但我想知道它是否正确,或者是否有更好的方法来完成这项任务 提前感谢您的回复使用android服务下载大文件的正确方法,android,performance,android-service,Android,Performance,Android Service,我为开始下载大文件创建了一个服务。我决定创建一个ThreadPoolExecutor,因为在我的应用程序中,它可以一次下载多个文件。在每个线程中,我添加一个我从活动中发送的名称。如果用户决定停止一个特定的download,我会使用它,这样就可以停止特定的线程 代码可以工作,但我想知道它是否正确,或者是否有更好的方法来完成这项任务 提前感谢您的回复 public class DownloadService extends Service { private static final String
public class DownloadService extends Service {
private static final String TAG = DownloadService.class.getName();
private Looper mServiceLooper;
private ServiceHandler mServiceHandler;
private LocalBroadcastManager mLocalBroadcastManager;
public static final String ACTION_MESSAGE = "it.myapplication.DownloadService.message";
public static final String ACTION_PROGRESS_BAR = "it.myapplication.DownloadService.progressbar";
private HandlerThread thread;
long id;
int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor executor = new ThreadPoolExecutor(
NUMBER_OF_CORES * 2,
NUMBER_OF_CORES * 2,
60L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>()
);
@Override
public void onCreate() {
mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
final String nameThread = intent.getStringExtra("nameThread");
boolean status = intent.getBooleanExtra("status", true);
if (status) {
executor.execute(new Runnable() {
public void run() {
id = Thread.currentThread().getId();
Log.d(TAG, TAG + " THREAD ID " + Thread.currentThread().getId());
Thread.currentThread().setName(String.valueOf(nameThread));
String name = Thread.currentThread().getName();
Log.d(TAG, TAG + " THREAD NAME " + name);
Intent intent_send = new Intent(ACTION_MESSAGE);
intent_send.putExtra("idThread", (int) id);
intent_send.putExtra("nameThread", nameThread);
mLocalBroadcastManager.sendBroadcast(intent_send);
downloadPackage(nameThread, (int) id);
}
});
}
else {
Set<Thread> setOfThread = Thread.getAllStackTraces().keySet();
for (Thread thread : setOfThread) {
if (thread.getName().equalsIgnoreCase(nameThread)) {
thread.interrupt();
}
}
this.stopSelf();
}
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onDestroy() {
Log.d(TAG, "DESTROY");
super.onDestroy();
}
private void downloadPackage(String nameThread, int id) {
Log.d("START DOWNLOAD", "START DOWNLOAD");
String urlToDownload = "url";
Intent intent_send = new Intent(ACTION_PROGRESS_BAR);
NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentTitle("Package Museum Download")
.setContentText("Download in progress")
.setSmallIcon(R.mipmap.ic_launcher);
try {
URL url = new URL(urlToDownload);
URLConnection connection = url.openConnection();
connection.connect();
// this will be useful so that you can show a typical 0-100% progress bar
int fileLength = connection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(connection.getInputStream());
Log.d("DIR ", "DIR " + getApplicationContext().getFilesDir());
OutputStream output = new FileOutputStream("/data/data/it.myapplication/files/" + nameThread + ".pdf");
byte data[] = new byte[1024];
long total = 0;
int count;
while ((count = input.read(data)) != -1) {
total += count;
// publishing the progress....
Bundle resultData = new Bundle();
resultData.putInt("progress", (int) (total * 100 / fileLength));
//Log.d(TAG, "PROGRESS DATA " + (int) (total * 100 / fileLength));
intent_send.putExtra("progress", (int) (total * 100 / fileLength));
mLocalBroadcastManager.sendBroadcast(intent_send);
mBuilder.setProgress(100, (int) (total * 100 / fileLength), false);
// Displays the progress bar for the first time.
mNotifyManager.notify(id, mBuilder.build());
output.write(data, 0, count);
}
// When the loop is finished, updates the notification
mBuilder.setContentText("Download complete")
.setProgress(0, 0, false);
mNotifyManager.notify(id, mBuilder.build());
output.flush();
output.close();
input.close();
} catch (IOException e) {
e.printStackTrace();
mNotifyManager.cancel(id);
}
}
公共类下载服务扩展服务{
私有静态最终字符串标记=DownloadService.class.getName();
专用活套;
私有服务处理程序mServiceHandler;
私人本地广播经理mLocalBroadcastManager;
公共静态最终字符串操作\u MESSAGE=“it.myapplication.DownloadService.MESSAGE”;
public static final String ACTION\u PROGRESS\u BAR=“it.myapplication.DownloadService.progressbar”;
私有句柄线程;
长id;
int NUMBER_OF_CORES=Runtime.getRuntime().AvailableProcessor();
ThreadPoolExecutor executor=新的ThreadPoolExecutor(
_芯数*2,
_芯数*2,
60L,
时间单位:秒,
新建LinkedBlockingQueue()
);
@凌驾
public void onCreate(){
mLocalBroadcastManager=LocalBroadcastManager.getInstance(this);
}
@凌驾
公共int onStartCommand(Intent Intent、int标志、int startId){
最终字符串nameThread=intent.getStringExtra(“nameThread”);
布尔状态=intent.getBooleanExtra(“状态”,true);
如果(状态){
executor.execute(新的Runnable(){
公开募捐{
id=Thread.currentThread().getId();
Log.d(标记,标记+“线程ID”+线程.currentThread().getId());
Thread.currentThread().setName(String.valueOf(nameThread));
字符串名称=Thread.currentThread().getName();
Log.d(标记,标记+线程名称+名称);
意向发送=新意向(行动信息);
intent_send.putExtra(“idThread”,(int)id);
intent_send.putExtra(“nameThread”,nameThread);
mLocalBroadcastManager.sendBroadcast(发送意图);
下载包(nameThread,(int)id);
}
});
}
否则{
Set setOfThread=Thread.getAllStackTraces().keySet();
用于(线程:setOfThread){
if(thread.getName().equalsIgnoreCase(nameThread)){
thread.interrupt();
}
}
这个。stopSelf();
}
返回开始时间;
}
@凌驾
公共IBinder onBind(意向){
抛出新的UnsupportedOperationException(“尚未实现”);
}
@凌驾
公共空间{
日志d(标签“销毁”);
super.ondestory();
}
私有void下载包(字符串nameThread,int-id){
Log.d(“开始下载”,“开始下载”);
字符串urlToDownload=“url”;
意向发送=新意向(行动进度条);
NotificationManager mNotifyManager=(NotificationManager)getSystemService(Context.NOTIFICATION\u服务);
NotificationCompat.Builder mBuilder=新的NotificationCompat.Builder(此);
mBuilder.setContentTitle(“包博物馆下载”)
.setContentText(“正在下载”)
.setSmallIcon(R.mipmap.ic_启动器);
试一试{
URL=新URL(urlToDownload);
URLConnection=url.openConnection();
connection.connect();
//这将非常有用,以便您可以显示典型的0-100%进度条
int fileLength=connection.getContentLength();
//下载该文件
InputStream输入=新的BufferedInputStream(connection.getInputStream());
Log.d(“DIR”、“DIR”+getApplicationContext().getFilesDir());
OutputStream output=新文件OutputStream(“/data/data/it.myapplication/files/”+nameThread+“.pdf”);
字节数据[]=新字节[1024];
长总计=0;
整数计数;
而((计数=输入。读取(数据))!=-1){
总数+=计数;
//发布进度。。。。
Bundle resultData=新Bundle();
resultData.putInt(“progress”,(int)(总计*100/文件长度));
//Log.d(标记“进度数据”+(int)(总计*100/文件长度));
intent_send.putExtra(“进度”(int)(总计*100/文件长度));
mLocalBroadcastManager.sendBroadcast(发送意图);
mBuilder.setProgress(100,(int)(总计*100/文件长度),false);
//第一次显示进度条。
mNotifyManager.notify(id,mBuilder.build());
输出.写入(数据,0,计数);
}
//循环完成后,更新通知
mBuilder.setContentText(“下载完成”)
.setProgress(0,0,false);
mNotifyManager.notify(id,mBuilder.build());
output.flush();
output.close();
input.close();
}捕获(IOE异常){
e、 printStackTrace();
mNotifyManager.cancel(id);
}
}
}只需使用android DownloadManager,谢谢@yazan。我不知道