使用AsyncTask和更新数据库时,UI会冻结

时间:2016-09-12 14:53:06

标签: android firebase android-asynctask firebase-realtime-database

我试图在我的Splash活动中添加AsyncTask - AsyncTask doInBackground()将从Firebase下载数据库信息(JSON),并将更新数据库。

我尝试使用ProgressDialog,直到数据更新并且Splash Activity进入下一个活动。如果我在ProgressDialog上将其解除,则onPostExecute()不会显示。

如果我删除dismiss()操作,则会显示,但我可以看到ProgressDialog冻结。很明显,我的代码并不正确。

我是Android开发的新手。请帮忙。

附加代码:

public class NationalSplashActivity2 extends Activity {

NationalDatabaseHelper NationalDB;
xDatabaseHelper xDB;
Cursor cursor;
String default_league;
private ProgressDialog mProgressDialog;



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.national_activity_splash);

    final ImageView iv = (ImageView) findViewById(R.id.nationalimageViewSplashScreen);

    BackgroundTask backgroundtask = new BackgroundTask(NationalSplashActivity2.this);
    backgroundtask.execute();

    Thread startTimer = new Thread(){
     public void run(){

             sleep(2000);
     }catch (InterruptedException e){
             e.printStackTrace();
         }

   };
    startTimer.start();
}

class BackgroundTask extends AsyncTask<String,String,String> {

    Context ctx;
    NationalDatabaseHelper NationalDB;
    xDatabaseHelper SecDB;



    BackgroundTask (Context ctx){

        this.ctx = ctx;
        mProgressDialog = new ProgressDialog(ctx);
        mProgressDialog.setMessage("Loading...");
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.setMax(100);
        mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        mProgressDialog.setCancelable(true);

    }

    @Override
    protected void onPreExecute() {
        //super.onPreExecute();
        mProgressDialog.show();
    }

    @Override
    protected String doInBackground(String... params) {

        NationalAllGamesUpdate();
        xAllGamesUpdate();

        return "";
    }

    @Override
    protected void onProgressUpdate(String... progress) {

        super.onProgressUpdate(progress);

        mProgressDialog.setProgress(Integer.parseInt(progress[0]));

    }

    @Override
    protected void onPostExecute(String result) {

        if (mProgressDialog.isShowing()) {
            mProgressDialog.dismiss();
        }

}


}

1 个答案:

答案 0 :(得分:0)

你在这里做什么是非常奇怪的..默认情况下,从firebase检索数据是一种异步操作,所以你不需要创建异步。只需下载数据,保存在数据库中,然后启动新活动。正如我所看到的,你创建了一个async来获取数据并保存到数据库并启动一个带睡眠的新线程,询问数据库,然后你开始新的Activity(如果我错了,请纠正我)。

这是错误的,因为您不确切知道何时检索进程并在数据库中保存并且您的线程是在一些休眠时间后访问数据库的字符串,其中数据库可以通过保存进程锁定或为空,因为检索没有完成。您可以在完成数据库中的保存过程后立即启动活动,并且可以使用来自firebase响应的数据来执行此操作。它可以节省更多的时间和内存。启动检索过程时可以显示“进度”对话框,并且需要在启动新活动之前将其关闭以防止内存泄漏。

编辑:您似乎已编辑了自己的问题。

再次编辑:

因此,您可以创建一个可以在数据库帮助程序构造函数中传递的接口,类似于:

new NationalDatabaseHelper(new MyCustomInterface() {})

其中MyCustomInterface可以有一个或多个方法,取决于您想要通知的内容。我认为它可以有方法void onTaskCompleted()或其他什么,并且在插入/删除或更新方法结束后调用此方法因为这些操作是同步的,所以最后你应该调用listener.onTaskCompleted()并在那里实现界面应该调用你想要做的事情。

我推荐的另一种方法,

NationalDatabaseHelper.addEntry(new MyCustomInterface(){});

在这种情况下更有用,因为您知道完成了哪些数据库操作。

你可以做任何你想做的事情,最适合你。希望你明白。