我正在尝试从ProgressBar
任务更新Service
。我实现了BroadcastReceiver
,以便可以与UI线程进行交互。我在主要活动中更新ProgressBar
,并从MyService活动中接收数据。 MyService活动将执行Async任务,并更新应通过OnProgressUpdate方法发送回的意图。
这是我的代码:
MainActivity:
package com.example.services;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.content.Intent;
import android.view.View;
import android.widget.ProgressBar;
import static android.content.Intent.ACTION_ATTACH_DATA;
public class MainActivity extends AppCompatActivity {
private MyBroadRequestReceiver receiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter filter = new IntentFilter(ACTION_ATTACH_DATA);
receiver = new MyBroadRequestReceiver();
registerReceiver( receiver, filter);
}
public void startService(View view) {
startService(new Intent(getBaseContext(), MyService.class));
//pb.setProgress();
}
public void stopService(View view) {
stopService(new Intent(getBaseContext(), MyService.class));
}
public class MyBroadRequestReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
ProgressBar pb = (ProgressBar) findViewById(R.id.progressbar);
int progress = intent.getFlags();
pb.setProgress(progress);
}
}
}
我的服务:
package com.example.services;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.net.MalformedURLException;
import java.net.URL;
import android.os.AsyncTask;
import android.util.Log;
import java.util.Timer;
import java.util.TimerTask;
public class MyService extends Service {
int counter = 0;
static final int UPDATE_INTERVAL = 1000;
private Timer timer = new Timer();
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
doSomethingRepeatedly();
try {
new DoBackgroundTask().execute(
new URL("http://www.amazon.com/somefiles.pdf"),
new URL("http://www.wrox.com/somefiles.pdf"),
new URL("http://www.google.com/somefiles.pdf"),
new URL("http://www.learn2develop.net/somefiles.pdf"));
} catch (MalformedURLException e) {
e.printStackTrace();
}
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
if (timer != null){
timer.cancel();
}
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
private void doSomethingRepeatedly() {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
Log.d("MyService", String.valueOf(++counter));
}
}, 0, UPDATE_INTERVAL);
}
private class DoBackgroundTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalBytesDownloaded = 0;
for (int i = 0; i < count; i++) {
totalBytesDownloaded += DownloadFile(urls[i]);
//Intent broadcastIntent = new Intent();
//broadcastIntent.setAction(Intent.ACTION_ATTACH_DATA);
//sendBroadcast(broadcastIntent);
publishProgress((int) (((i + 1) / (float) count) * 100));
}
return totalBytesDownloaded;
}
protected void onProgressUpdate(Integer... progress) {
Log.d("Downloading files", String.valueOf(progress[0]) + "% downloaded");
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.example.services.MainActivity");
//broadcastIntent.putExtra("progress",progress);
broadcastIntent.setFlags(progress[0]);
sendBroadcast(broadcastIntent);
Toast.makeText(getBaseContext(),
String.valueOf(progress[0]) + "% downloaded-"+counter,
Toast.LENGTH_LONG).show();
}
protected void onPostExecute(Long result) {
Toast.makeText(getBaseContext(), "Downloaded " + result + " bytes",
Toast.LENGTH_LONG).show();
//stopSelf();
}
}
private int DownloadFile(URL url) {
try {
//---simulate taking some time to download a file---
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//---return an arbitrary number representing
// the size of the file downloaded---
return 100;
}
}
请看看我的onProgressUpdate
,并告诉我是否正在这样做。我的ProgressBar根本没有更新。
答案 0 :(得分:0)
因为您没有startService ononCreate()方法。服务将无法运行。
答案 1 :(得分:0)
所有这些都不是您解决问题的好方法。请浏览Google Android文档Backgournd guide
我建议您切换到DownloadManager。
答案 2 :(得分:0)
您的意图过滤器定义为“ ACTION_ATTACH_DATA”
IntentFilter filter = new IntentFilter(ACTION_ATTACH_DATA);
所以,像这样发送广播:
Intent i = new Intent(ACTION_ATTACH_DATA);
sendBroadcast(i);
此外,不要忘记在onDestroy上取消注册广播
答案 3 :(得分:0)
您的代码存在一些问题。
首先,如果您需要通过服务更新活动的进度条,那么有效的方法是使用LocalBroadcastManager
而不是常规广播(称为全局广播)。
第二,因为在服务中,您使用broadcastIntent.setAction("com.example.services.MainActivity");
,然后在活动中,必须使用相同的操作来接收广播。
IntentFilter filter = new IntentFilter("com.example.services.MainActivity");
代替
IntentFilter filter = new IntentFilter(ACTION_ATTACH_DATA);
最后,由于在服务中使用AsyncTask,为避免服务的泄漏上下文,建议的方法是将asynctask声明为静态类。
全部放在一起。
MyService.java
public class MyService extends Service {
int counter = 0;
static final int UPDATE_INTERVAL = 1000;
private Timer timer = new Timer();
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
doSomethingRepeatedly();
try {
new DoBackgroundTask(this).execute(
new URL("http://www.amazon.com/somefiles.pdf"),
new URL("http://www.wrox.com/somefiles.pdf"),
new URL("http://www.google.com/somefiles.pdf"),
new URL("http://www.learn2develop.net/somefiles.pdf"));
} catch (MalformedURLException e) {
e.printStackTrace();
}
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
if (timer != null) {
timer.cancel();
}
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
private void doSomethingRepeatedly() {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
Log.d("MyService", String.valueOf(++counter));
}
}, 0, UPDATE_INTERVAL);
}
// Declare asynctask as static class.
private static class DoBackgroundTask extends AsyncTask<URL, Integer, Long> {
// Using WeakReference to keep the context of the service to avoid leaking.
private WeakReference<Context> mContext;
DoBackgroundTask(Context context) {
mContext = new WeakReference<>(context);
}
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalBytesDownloaded = 0;
for (int i = 0; i < count; i++) {
totalBytesDownloaded += DownloadFile(urls[i]);
//Intent broadcastIntent = new Intent();
//broadcastIntent.setAction(Intent.ACTION_ATTACH_DATA);
//sendBroadcast(broadcastIntent);
publishProgress((int) (((i + 1) / (float) count) * 100));
}
return totalBytesDownloaded;
}
protected void onProgressUpdate(Integer... progress) {
Log.d("Downloading files", String.valueOf(progress[0]) + "% downloaded");
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("com.example.services.MainActivity");
//broadcastIntent.putExtra("progress",progress);
broadcastIntent.setFlags(progress[0]);
Context context = mContext.get();
if (context != null) {
LocalBroadcastManager.getInstance(context).sendBroadcast(broadcastIntent);
int counter = ((MyService)context).counter;
Toast.makeText(context,
String.valueOf(progress[0]) + "% downloaded-" + counter,
Toast.LENGTH_LONG).show();
}
}
protected void onPostExecute(Long result) {
Context context = mContext.get();
if (context != null) {
Toast.makeText(context, "Downloaded " + result + " bytes",
Toast.LENGTH_LONG).show();
//stopSelf();
}
}
private int DownloadFile(URL url) {
try {
//---simulate taking some time to download a file---
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//---return an arbitrary number representing
// the size of the file downloaded---
return 100;
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private MyBroadRequestReceiver receiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onStart() {
super.onStart();
// Register broadcast receiver.
IntentFilter filter = new IntentFilter("com.example.services.MainActivity");
receiver = new MyBroadRequestReceiver();
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);
}
@Override
protected void onStop() {
// Unregister broadcast receiver.
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
super.onStop();
}
public void startService(View view) {
startService(new Intent(getBaseContext(), MyService.class));
}
public void stopService(View view) {
stopService(new Intent(getBaseContext(), MyService.class));
}
public class MyBroadRequestReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ProgressBar pb = (ProgressBar) findViewById(R.id.progressbar);
int progress = intent.getFlags();
pb.setProgress(progress);
}
}
}