Android-下载文件+;状态栏通知使手机变慢
我目前有一个Android-下载文件+;状态栏通知使手机变慢,android,notifications,download,android-asynctask,slowdown,Android,Notifications,Download,Android Asynctask,Slowdown,我目前有一个asynctask,可以从服务器下载mp3。当用户开始下载时,将创建一个状态栏通知。这将实时显示下载进度。我唯一担心的是手机的速度太慢了。是否有任何方法可以延迟显示的进度或使代码更快?谢谢 代码如下: public class DownloadFile extends AsyncTask<String, String, String> { CharSequence contentText; Context context; CharSequence
asynctask
,可以从服务器下载mp3。当用户开始下载时,将创建一个状态栏通知。这将实时显示下载进度。我唯一担心的是手机的速度太慢了。是否有任何方法可以延迟显示的进度或使代码更快?谢谢
代码如下:
public class DownloadFile extends AsyncTask<String, String, String> {
CharSequence contentText;
Context context;
CharSequence contentTitle;
PendingIntent contentIntent;
int HELLO_ID = 1;
long time;
int icon;
CharSequence tickerText;
File file;
public void downloadNotification() {
String ns = Context.NOTIFICATION_SERVICE;
notificationManager = (NotificationManager) getSystemService(ns);
icon = R.drawable.sdricontest;
//the text that appears first on the status bar
tickerText = "Downloading...";
time = System.currentTimeMillis();
notification = new Notification(icon, tickerText, time);
context = getApplicationContext();
//the bold font
contentTitle = "Your download is in progress";
//the text that needs to change
contentText = "0% complete";
Intent notificationIntent = new Intent(Intent.ACTION_VIEW);
notificationIntent.setType("audio/*");
contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
notificationManager.notify(HELLO_ID, notification);
}
@Override
protected void onPreExecute() {
//execute the status bar notification
downloadNotification();
super.onPreExecute();
}
@Override
protected String doInBackground(String... url) {
int count;
try {
URL url2 = new URL(sdrUrl);
HttpURLConnection connection = (HttpURLConnection) url2.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.connect();
int lengthOfFile = connection.getContentLength();
//make the stop drop rave folder
File sdrFolder = new File(Environment.getExternalStorageDirectory() + "/StopDropRave");
boolean success = false;
if (!sdrFolder.exists()) {
success = sdrFolder.mkdir();
}
if (!success) {
String PATH = Environment.getExternalStorageDirectory()
+ "/StopDropRave/";
file = new File(PATH);
file.mkdirs();
} else {
String PATH = Environment.getExternalStorageDirectory()
+ "/StopDropRave/";
file = new File(PATH);
file.mkdirs();
}
String[] path = url2.getPath().split("/");
String mp3 = path[path.length - 1];
String mp31 = mp3.replace("%20", " ");
String sdrMp3 = mp31.replace("%28", "(");
String sdrMp31 = sdrMp3.replace("%29", ")");
String sdrMp32 = sdrMp31.replace("%27", "'");
File outputFile = new File(file, sdrMp32);
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream input = connection.getInputStream();
byte[] data = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress("" + (int) (total * 100 / lengthOfFile));
fos.write(data, 0, count);
}
fos.close();
input.close();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
public void onProgressUpdate(String... progress) {
contentText = Integer.parseInt(progress[0]) + "% complete";
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
notificationManager.notify(HELLO_ID, notification);
super.onProgressUpdate(progress);
}
}
公共类下载文件扩展异步任务{
字符序列内容文本;
语境;
字符序列内容标题;
悬而未决的意图;
int HELLO_ID=1;
长时间;
int图标;
字符序列tickerText;
文件;
公共无效下载通知(){
字符串ns=Context.NOTIFICATION\u服务;
notificationManager=(notificationManager)getSystemService(ns);
icon=R.drawable.sdricontest;
//首先出现在状态栏上的文本
tickerText=“正在下载…”;
时间=System.currentTimeMillis();
通知=新通知(图标、tickerText、时间);
context=getApplicationContext();
//粗体字
contentTitle=“您的下载正在进行”;
//需要更改的文本
contentText=“0%完成”;
Intent notificationIntent=新意图(Intent.ACTION\u视图);
notificationIntent.setType(“音频/*”);
contentIntent=PendingEvent.getActivity(上下文,0,notificationIntent,0);
setLateStevenInfo(上下文、contentTitle、contentText、contentIntent);
notificationManager.notify(HELLO_ID,notification);
}
@凌驾
受保护的void onPreExecute(){
//执行状态栏通知
下载通知();
super.onPreExecute();
}
@凌驾
受保护的字符串doInBackground(字符串…url){
整数计数;
试一试{
URL url2=新URL(SDURL);
HttpURLConnection connection=(HttpURLConnection)url2.openConnection();
connection.setRequestMethod(“GET”);
connection.setDoOutput(真);
connection.connect();
int lengthOfFile=connection.getContentLength();
//使停止放置rave文件夹
File sdrFolder=新文件(Environment.getExternalStorageDirectory()+“/StopDropRave”);
布尔成功=假;
如果(!sdrFolder.exists()){
success=sdrFolder.mkdir();
}
如果(!成功){
String PATH=Environment.getExternalStorageDirectory()
+“/StopDropRave/”;
文件=新文件(路径);
mkdirs()文件;
}否则{
String PATH=Environment.getExternalStorageDirectory()
+“/StopDropRave/”;
文件=新文件(路径);
mkdirs()文件;
}
字符串[]path=url2.getPath().split(“/”);
字符串mp3=path[path.length-1];
字符串mp31=mp3.replace(“%20”和“”);
字符串sdrm3=mp31。替换(“%28”和“(”);
字符串sdrMp31=sdrm3.replace(“%29”,”);
字符串sdrMp32=sdrMp31.replace(“%27”和“”);
File outputFile=新文件(文件,sdrMp32);
FileOutputStream fos=新的FileOutputStream(outputFile);
InputStream输入=连接。getInputStream();
字节[]数据=新字节[1024];
长总计=0;
而((计数=输入。读取(数据))!=-1){
总数+=计数;
出版进度(“+(int)(总计*100/长办公室));
fos.写入(数据,0,计数);
}
fos.close();
input.close();
}捕获(IllegalArgumentException e){
e、 printStackTrace();
}捕获(非法状态){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}
返回null;
}
@凌驾
public void onProgressUpdate(字符串…进度){
contentText=Integer.parseInt(进度[0])+%complete;
setLateStevenInfo(上下文、contentTitle、contentText、contentIntent);
notificationManager.notify(HELLO_ID,notification);
super.onProgressUpdate(进度);
}
}
我看到了类似的结果,你不需要经常推送更新通知,我将我的更新更改为每秒只更新几次。(例如,在onProgressUpdate中,记录您上次调用notify的时间,并且仅当您上次调用的时间超过100毫秒,或者处于最大值时才调用notify。我遇到了同样的问题,即即使间隔3秒也无法更新进度条通知,因此经过数小时的挖掘后,我意识到H无论何时更新通知,都必须重新实例化RemoteView对象,并将其初始化为通知对象的contentView。完成此操作后,我能够以100ms-500ms的间隔更新通知进度条,并且在很长的一段时间内不会遇到任何UI阻塞
注意:如果您不同意,您可以在注释标记行后运行此代码段来验证此答案,并查看差异。可能需要大约5分钟才能启动严重的UI阻塞,这将使设备发热并可能停止运行。
我尝试使用Android 4.2.2的S3 mini,updateNotification(..)方法是从服务内的工作线程调用的。而且我已经对它进行了双重检查,不知道在使用Notification.Builder时会发生什么情况。
注:在3年的问题之后写下这个答案的原因是因为我想知道,我甚至没有找到一个stackoverflow的答案或其他博客帖子,用这个非常简单的解决方案来处理这个严重的问题
我希望
//long mMaxtTimeoutNanos = 1000000000 // 1000ms.
long mMinTimeNanos = 100000000;//100ms minimum update limit. For fast downloads.
long mMaxtTimeoutNanos = 500000000;//500ms maximum update limit. For Slow downloads
long mLastTimeNanos = 0;
private void updateNotification(.....){
// Max Limit
if (mUpdateNotification || ((System.nanoTime()-mLastTimeNanos) > mMaxtTimeoutNanos)) {
// Min Limit
if (((System.nanoTime() - mLastTimeNanos) > mMinTimeNanos)) {
mLastTimeNanos = System.nanoTime();
// instantiate new RemoteViews object.
// (comment out this line and instantiate somewhere
// to verify that the above told answer is true)
mRemoteView = new RemoteViews(getPackageName(),
R.layout.downloader_notification_layout);
// Upate mRemoteView with changed data
...
...
// Initialize the already existing Notification contentView
// object with newly instatiated mRemoteView.
mNotification.contentView = mRemoteView;
mNotificationManager.notify(mNotificatoinId, mNotification);
mUpdateNotification = false;
}
}
}
class DownloadMaterial extends AsyncTask<String, String, String> {
CountDownTimer cdt;
int id = i;
NotificationManager mNotifyManager;
NotificationCompat.Builder mBuilder;
@Override
protected void onPreExecute() {
/**
* Create custom Count Down Timer
*/
cdt = new CountDownTimer(100 * 60 * 1000, 500) {
public void onTick(long millisUntilFinished) {
mNotifyManager.notify(id, mBuilder.build());
}
public void onFinish() {
mNotifyManager.notify(id, mBuilder.build());
}
};
}
@Override
protected String doInBackground(String... strings) {
/**
* Start timer to update Notification
* Set Progress to 20 after connection
* Build Notification
* Increment Progress
* Download and Save file
*/
try {
mNotifyManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(context);
mBuilder.setContentTitle("Downloading File")
.setContentText(file_name)
.setProgress(0, 100, false)
.setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(Notification.PRIORITY_LOW);
// Initialize Objects here
publishProgress("5");
mNotifyManager.notify(id, mBuilder.build());
cdt.start();
// Create connection here
publishProgress("20");
// Download file here
while ((count = input.read(data)) != -1) {
total += count;
publishProgress("" + (int) (20 + (total * 80 / fileLength)));
output.write(data, 0, count);
}
} catch (Exception e) {
return "Failed";
}
return "Success";
}
@Override
protected void onProgressUpdate(String... values) {
/**
* Update Download Progress
*/
mBuilder.setContentInfo(values[0] + "%")
.setProgress(100, Integer.parseInt(values[0]), false);
}
@Override
protected void onPostExecute(String s) {
String title;
if (s.equals("Success")) {
title = "Downloaded";
} else {
title = "Error Occurred";
}
mBuilder.setContentTitle(title)
.setContentInfo("")
.setOngoing(false)
.setProgress(0, 0, false);
cdt.onFinish();
cdt.cancel();
}
}
// While loop from generic download method.
int previousProgress = 0;
while ((count = inputStream.read(buff)) != -1) {
outputStream.write(buff, 0, count);
totalBytesDownloaded += count;
int prog = (int) (totalBytesDownloaded * 100 / contentLength);
if (prog > previousProgress) {
// Only post progress event if we've made progress.
previousProgress = prog;
myPostProgressMethod(prog);
}
}