我有一个更新数据库操作,它有一个活动,它不断更新百分比并在AsyncTask中运行。
内部doInBackground()我调用更新数据库的控制器并不断更新活动的百分比,但是,如果按下主页按钮或后退按钮,操作将被取消。你建议我做什么?
我试图在doInBackground()中启动一个服务,所以它会在后台运行,但它看起来不起作用。
我的代码如下所示:
public class UpdateDatabaseAsyncTask extends AsyncTask<Void, Integer, Integer>
{
@Override
public void onPreExecute()
{
mCustomProgressBar.startAnimation();
}
@Override
public Integer doInBackground(Void... params)
{
return mController.updateDatabase();
}
@Override
public void onPostExecute(Integer result)
{
mCustomProgressBar.stopAnimation();
// finish the activity
}
@Override
public void onProgressUpdate(Integer... value)
{
updatePercentageValue(value[0]);
}
public void callPublishProgress(Integer value)
{
publishProgress(value);
}
}
在控制器内部,我调用方法callPublishProgress(value)
传递当前百分比值,因此它将在UI中publishProgress(value)
。
我正在调试,我按下了home / back按钮,它刚停止运行工作线程。
我试过的另一个解决方案是启动服务在后台运行,无论用户是否按下主页/后退按钮,所以我想,服务会调用执行工作的控制器方法,然后会调用callPublishProgress(value)
来更新UI上的百分比值。
然而,正在发生的事情是,代码到达doInBackground()
并启动服务,但它会立即转到onPostExecute()
,它只是没有等待服务完成(当然!)。所以它给出NullPointerException
。我想在doInBackground()
内部设置一个循环,并在服务中设置了一个标志,所以它会在服务尚未完成时离开这个循环(我使用的是IntentService),但它无论如何都不起作用。
我还想过使用Timer。但我不知道。
我正在阅读有关Threads等文档的文章。它建议使用AsyncTask
,正如我试图做的那样。它还讨论了runOnUiThread(Runnable)
。
无论如何我需要的是在后台进行操作(可能使用IntentService),所以无论用户按下主页按钮,它都会继续运行,但它必须更新UI上的百分比,当用户离开屏幕并返回屏幕时,它会显示屏幕中更新的当前百分比值。
对我来说,最好的解决方案是什么?
感谢。
答案 0 :(得分:4)
public class MyServce extends Service{
public static final String BROADCAST_ACTION = "com.myapp";
Intent intent;
private final Handler handler = new Handler();
@Override
public void onCreate()
{
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
}
@Override
public void onStart(Intent intent, int startId) {
handler.removeCallbacks(sendUpdatesToUI);
handler.postDelayed(sendUpdatesToUI, 1000); // 1 second
}
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
DoYourWorking();
handler.postDelayed(this, 1000); // 1 seconds
}
private void DoYourWorking() {
........
........
intent.putExtra("key", progress);
sendBroadcast(intent);
}
};
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(sendUpdatesToUI);
}
现在在您的活动注册中广播到服务
private BroadcastReceiver brodcast = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//intent.getWhatever
// update your progress
//progressbar.setProgress
}
注册广播
registerReceiver(brodcast, new IntentFilter(MyService.BROADCAST_ACTION));
答案 1 :(得分:1)
这对我有用。我在一个线程上启动了一个后台服务,该线程只获取值并更新单个对象中的对象。
在视图控制器中,我启动一个计时器,通过以单例形式从对象中获取数据来不断更新视图。
我对整个问题文本有一点了解,所以我不确定你是否尝试过这个问题。但这是有效的。此外,该服务以START_STICKY
答案 2 :(得分:1)
使用IntentService(自己的线程上的服务)和Handler将数据传回活动。