无限 while 循环,而 AsyncTask 未完成
infinite while loop, while AsyncTask is not finish
我有一个 SplashScreen Activity,它调用 Asynctask Class 在 Internet 上获取信息。
我想等待我的 Asynctask 未完成(互联网速度连接期间的时间)
我的activity:
public static boolean test = true;
[...]
final Liste en_ce_moment = new Liste("En ce moment au cinéma", nowMovie);
mesListes.add(en_ce_moment);
//call my Asynctask file
fetchNowMovie process = new fetchNowMovie();
process.execute();
while(test)
{
}
Intent i = new Intent(SplashScreenActivity.this, MainActivity.class);
startActivity(i);
我的异步任务:
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
SplashScreenActivity.test = false;
SplashScreenActivity.nowMovie.clear();
SplashScreenActivity.nowMovie.addAll(list);
}
从逻辑上讲,布尔值在 onPostExecute
中变为假,因此 while 循环停止并且意图必须开始但 while 循环永远不会停止...
这看起来像是隐藏在另一个问题中的问题,但要解决第一级问题,您可以尝试使用 CountDownLatch
而不是静态布尔值:
CountDownLatch latch = new CountDownLatch(1);
fetchNowMovie process = new fetchNowMovie(latch);
process.execute();
latch.await();
Intent i = new Intent(SplashScreenActivity.this, MainActivity.class);
startActivity(i);
您必须接受闩锁作为 AsyncTask 构造函数的一部分:
private final CountDownLatch latch;
public fetchNowMovie(CountDownLatch latch) {
this.latch = latch;
}
// ...
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
latch.countDown();
SplashScreenActivity.nowMovie.clear();
SplashScreenActivity.nowMovie.addAll(list);
}
尝试使用非常简单的库:
https://github.com/Arasthel/AsyncJobLibrary
开始你的 Splash activity:
Intent i = new Intent(context, SplashScreenActivity.class);
startActivity(i);
在 Splash 的 "onCreate" 方法中 activity 做,你需要在后台和任务完成后,在主线程上做(更新列表):
AsyncJob.doInBackground(new AsyncJob.OnBackgroundJob() {
@Override
public void doOnBackground() {
//load from local DB or http-request:
List<Movie> movieList = fetchNowMovie();
//You can convert movieList to Json string, for example and save in SharedPreferences. Or you can use local DB for saving new movies.
// Send the result to the UI thread and show it
AsyncJob.doOnMainThread(new AsyncJob.OnMainThreadJob() {
@Override
public void doInUIThread() {
Intent i = new Intent(splashScreenContext, MainActivity.class);
startActivity(i);
//load movies from shared preferences or local Database in MainActivity (onCreate)
}
});
}
});
连接库(应用项目目录中build.gradle):
dependencies {
...
implementation 'com.arasthel:asyncjob-library:1.0.3'
...
}
让我们使用简单的 interface
逻辑以安全的方式做您想做的事:
所以我们添加了简单的 interface
并重新定义了 MyAsnycTask
class 的 constructor
,如下所示:
public class MyAsnycTask extends AsyncTask
{
OnTaskFinished listener;
// Our simple interface
public interface OnTaskFinished {
void TimeToNextActivity();
}
// Your MyAsnycTask class constructor
public MyAsnycTask(OnTaskFinished l) {
listener = l;
}
. . .
作为 onPostExecute()
中的最后一行代码,我们已经完成了我们正在做的任何事情。所以通过我们的 listener
告诉我们:
listener.TimeToNextActivity();
要使用我们之前添加的 interface
,您的 Activity
必须 implements
它。所以我们实施它。在实现的方法中,我们使用 Intent
:
转到下一个 Activity
public class MyActivity extends Activity
implements MyAsnycTask.OnTaskFinished
{
@Override
public void TimeToNextActivity()
{
// Here go to next activity
Intent i = new Intent(this, MainActivity.class);
startActivity(i);
}
当我们修改 MyAsnycTask
class 的 constructor
时,我们必须像这样初始化它:
MyAsnycTask process = new MyAsnycTask(this);
process.execute();
我有一个 SplashScreen Activity,它调用 Asynctask Class 在 Internet 上获取信息。
我想等待我的 Asynctask 未完成(互联网速度连接期间的时间)
我的activity:
public static boolean test = true;
[...]
final Liste en_ce_moment = new Liste("En ce moment au cinéma", nowMovie);
mesListes.add(en_ce_moment);
//call my Asynctask file
fetchNowMovie process = new fetchNowMovie();
process.execute();
while(test)
{
}
Intent i = new Intent(SplashScreenActivity.this, MainActivity.class);
startActivity(i);
我的异步任务:
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
SplashScreenActivity.test = false;
SplashScreenActivity.nowMovie.clear();
SplashScreenActivity.nowMovie.addAll(list);
}
从逻辑上讲,布尔值在 onPostExecute
中变为假,因此 while 循环停止并且意图必须开始但 while 循环永远不会停止...
这看起来像是隐藏在另一个问题中的问题,但要解决第一级问题,您可以尝试使用 CountDownLatch
而不是静态布尔值:
CountDownLatch latch = new CountDownLatch(1);
fetchNowMovie process = new fetchNowMovie(latch);
process.execute();
latch.await();
Intent i = new Intent(SplashScreenActivity.this, MainActivity.class);
startActivity(i);
您必须接受闩锁作为 AsyncTask 构造函数的一部分:
private final CountDownLatch latch;
public fetchNowMovie(CountDownLatch latch) {
this.latch = latch;
}
// ...
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
latch.countDown();
SplashScreenActivity.nowMovie.clear();
SplashScreenActivity.nowMovie.addAll(list);
}
尝试使用非常简单的库: https://github.com/Arasthel/AsyncJobLibrary
开始你的 Splash activity:
Intent i = new Intent(context, SplashScreenActivity.class);
startActivity(i);
在 Splash 的 "onCreate" 方法中 activity 做,你需要在后台和任务完成后,在主线程上做(更新列表):
AsyncJob.doInBackground(new AsyncJob.OnBackgroundJob() {
@Override
public void doOnBackground() {
//load from local DB or http-request:
List<Movie> movieList = fetchNowMovie();
//You can convert movieList to Json string, for example and save in SharedPreferences. Or you can use local DB for saving new movies.
// Send the result to the UI thread and show it
AsyncJob.doOnMainThread(new AsyncJob.OnMainThreadJob() {
@Override
public void doInUIThread() {
Intent i = new Intent(splashScreenContext, MainActivity.class);
startActivity(i);
//load movies from shared preferences or local Database in MainActivity (onCreate)
}
});
}
});
连接库(应用项目目录中build.gradle):
dependencies {
...
implementation 'com.arasthel:asyncjob-library:1.0.3'
...
}
让我们使用简单的 interface
逻辑以安全的方式做您想做的事:
所以我们添加了简单的 interface
并重新定义了 MyAsnycTask
class 的 constructor
,如下所示:
public class MyAsnycTask extends AsyncTask
{
OnTaskFinished listener;
// Our simple interface
public interface OnTaskFinished {
void TimeToNextActivity();
}
// Your MyAsnycTask class constructor
public MyAsnycTask(OnTaskFinished l) {
listener = l;
}
. . .
作为 onPostExecute()
中的最后一行代码,我们已经完成了我们正在做的任何事情。所以通过我们的 listener
告诉我们:
listener.TimeToNextActivity();
要使用我们之前添加的 interface
,您的 Activity
必须 implements
它。所以我们实施它。在实现的方法中,我们使用 Intent
:
Activity
public class MyActivity extends Activity
implements MyAsnycTask.OnTaskFinished
{
@Override
public void TimeToNextActivity()
{
// Here go to next activity
Intent i = new Intent(this, MainActivity.class);
startActivity(i);
}
当我们修改 MyAsnycTask
class 的 constructor
时,我们必须像这样初始化它:
MyAsnycTask process = new MyAsnycTask(this);
process.execute();