6

我有一个更新数据库操作,它有一个活动,它不断更新百分比,它在 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)传递当前百分比值的方法,所以它会publishProgress(value)在 UI 中。

我正在调试,我按下了主页/返回按钮,它刚刚停止运行工作线程。


我尝试过的另一个解决方案是,无论用户是否按下主页/返回按钮,都启动一个在后台运行的服务,所以我想,服务会调用执行工作的控制器方法,它会调用callPublishProgress(value)无论如何都要更新 UI 上的百分比值。

然而,发生的事情是,代码到达doInBackground() 并启动服务,但它立即进入onPostExecute(),它只是没有等待服务完成(当然!)。所以它给出了一个NullPointerException. 我想doInBackground()在服务中设置一个标志来创建一个循环,所以它会在服务尚未完成时离开这个循环(我使用的是 IntentService),但它无论如何都不起作用。

我也想过使用计时器。但我不知道。

我正在阅读有关线程等的文档中的文章。它建议使用AsyncTask,就像我尝试做的那样。它还谈到runOnUiThread(Runnable).

无论如何,我需要的是在后台进行操作(可能使用 IntentService),所以无论用户是否按下主页按钮,它都会继续运行,但它必须更新 UI 上的百分比,并且当用户离开时屏幕并返回它,它显示屏幕中更新的当前百分比值。

我的情况的最佳解决方案是什么?

谢谢。

4

3 回答 3

5
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));
于 2012-04-27T17:32:45.017 回答
1

这对我有用。我在一个线程上启动了一个后台服务,它只获取值并更新单例中的对象。

在视图控制器中,我启动了一个计时器,它通过从单例对象中获取数据来不断更新视图。

我在理解你的整个问题文本时遇到了一点问题,所以我不确定你是否尝试过这个。但这是有效的。此外,该服务开始于START_STICKY

于 2012-04-27T17:24:59.710 回答
1

使用IntentService(它自己的线程上的 Service)和Handler将数据传回 Activity。

于 2012-04-27T17:30:53.947 回答