我目前正在开展一个项目SplashScreen
,需要启动AsyncTask#1
,然后AsyncTask#2
启用AsyncTask#5
。完成所有操作后,应将用户带到HomeActivity
。
AsyncTask#1
加载所有其他任务所需的数据。此外,我需要AsyncTask#2
到AsyncTask#5
来共享相同的布局(ImageView + TextView)。
基本上,就像加载屏幕一样:TextView: "Loading items"
和ImageView: item currently being loaded
。即使图像将快速滚动,我仍然必须让用户看到图像加载/更改。
我正在手动编写以下内容,因此请忽略语法错误(如果有):/
目前,我的splashScreen
看起来像这样:
try {
DatabaseSetup async1 = new DatabaseSetup(this);
async1.execute().get;
new Async2.execute();
new Async3.execute();
new Async4.execute();
new Async5.execute();
} finally {
Intent i = new Intent(this, HomePage.class);
StartActivity(i);
}
Async2 to 5
:
class Async# extends AsyncTask<Void, String, Boolean> {
private Context context;
private Activity activity;
private TextView tv;
private ImageView iv;
public Async#(Context context) {
this.context = context;
this.activity = (Activity) context;
}
onPreExecute() {
super.onPreExecute();
tv = (TextView) activity.findViewById(R.id.tvLoader);
iv = (ImageView) activity.findViewById(R.id.ivLoader);
}
doInBackground() {
publishProgress("Running Async#");
.
.
.
for(int i=0; i < items.length; i++) {
publishProgress(item[i].getImageLink());
}
}
onProgress(String... values) {
if(values[0].contains("Loading")
tvLoader.setText(values[0]);
else()
ivLoader.setImageURL(values[0]);
}
}
那么,这样做的正确方法是什么?我在某处读到如果我使用async1.execute().get()
,只有在Async1完成后才会调用以下行。我完全糊涂了。此代码有效,但有时会得到Surface#2 is not valid.
。
我不确定我是否要使用inflater? ImageView实际上是一个我从Loopj(SmartImageView)获取的库来缓存我得到的图像。
logcat的:
12-21 16:45:16.722: E/ViewSystem(8941): ViewRootImpl #2 Surface is not valid.
12-21 16:45:16.772: D/AbsListView(8941): Get MotionRecognitionManager
12-21 16:45:16.782: D/AbsListView(8941): onVisibilityChanged() is called, visibility : 4
12-21 16:45:16.782: D/AbsListView(8941): unregisterIRListener() is called
12-21 16:45:16.782: D/AbsListView(8941): onVisibilityChanged() is called, visibility : 0
12-21 16:45:16.782: D/AbsListView(8941): unregisterIRListener() is called
12-21 16:45:16.852: D/libEGL(8941): loaded /system/lib/egl/libEGL_adreno200.so
12-21 16:45:16.852: D/libEGL(8941): loaded /system/lib/egl/libGLESv1_CM_adreno200.so
12-21 16:45:16.862: D/libEGL(8941): loaded /system/lib/egl/libGLESv2_adreno200.so
12-21 16:45:16.862: I/Adreno200-EGL(8941): <qeglDrvAPI_eglInitialize:265>: EGL 1.4 QUALCOMM build: HAREESHG_Nondeterministic_AU+PATCH[ES]_msm8960_JB_1.9.6_MR2_CL3219408_release_ENGG (CL3219408)
12-21 16:45:16.862: I/Adreno200-EGL(8941): Build Date: 09/28/13 Sat
12-21 16:45:16.862: I/Adreno200-EGL(8941): Local Branch: hhh
12-21 16:45:16.862: I/Adreno200-EGL(8941): Remote Branch: quic/jb_1.9.6_1
12-21 16:45:16.862: I/Adreno200-EGL(8941): Local Patches: 8d50ec23e42ef52b570aa6ff1650afac0b503d78 CL3219408: Fix in the Glreadpixels for negative offsets and larger dimensions.
12-21 16:45:16.862: I/Adreno200-EGL(8941): 801859126f6ca69482b39a34ca61447e3f7cded8 rb: fix panel settings to clear undrawn/undefined buffers
12-21 16:45:16.862: I/Adreno200-EGL(8941): Reconstruct Branch: LOCAL_PATCH[ES]
12-21 16:45:16.902: D/OpenGLRenderer(8941): Enabling debug mode 0
12-21 16:45:16.932: D/AbsListView(8941): unregisterIRListener() is called
12-21 16:45:16.952: D/AbsListView(8941): unregisterIRListener() is called
12-21 16:45:17.022: D/AbsListView(8941): unregisterIRListener() is called
12-21 16:45:17.052: D/AbsListView(8941): unregisterIRListener() is called
非常感谢您阅读所有这些内容!
答案 0 :(得分:1)
您可以使用简单的信号量方法。 让你的Splash活动实现一个简单的界面:
public interface DecrementCallback{
public void setCount(int cnt);
public void onDecrementCount();
}
将成员定义为计数器:
private int cnt = 0;
您要实施的方法应该是:
@Override
public void setCount(int cnt) {
this.cnt = cnt;
}
@Override
public void onDecrementCount() {
cnt--;
if(cnt <= 0){
/**
* Start your main activity
*/
}
}
在启动asyntasks之前,设置计数器值:
setCount(5);
将此方法添加到您的asynctasks:
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
((DecrementCallback)activity).onDecrementCount();
}
当您在所有异步通信中共享相同的TextView和ImageView时,您应该非常了解自己所做的事情,因为如果您没有正确更新,可能会让用户感到困惑。
修改强>
如果要按顺序运行asynctasks(首先是Async1,然后是Asyn2,然后是Async3),可以将onPostExecute()方法修改为:
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
((DecrementCallback)activity).onDecrementCount();
if(this instanceof Async1){
new Async2(activity).execute();
}else if(this instanceof Async2){
new Async3(activity).execute();
}else if(this instanceof Async3){
new Async4(activity).execute();
}else if(this instanceof Async4){
new Async5(activity).execute();
}
}
然后,您只需要在活动中启动Async1。
编辑2:
如果要从Splash活动启动所有异步任务,可以将回调修改为:
public static interface DecrementCallback{
public void setCount(int cnt);
public void onDecrementCount(AsyncTask<Void, Void, Void> task);
}
asynctask方法应该是:
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
((DecrementCallback)activity).onDecrementCount(this);
}
您活动中的覆盖方法应如下所示:
@Override
public void onDecrementCount(AsyncTask<Void, Void, Void> task) {
cnt--;
if(cnt <= 0){
/**
* Start your main activity
*/
}
if(task instanceof Async1){
new Async2(activity).execute();
}else if(task instanceof Async2){
new Async3(activity).execute();
}else if(task instanceof Async3){
new Async4(activity).execute();
}else if(task instanceof Async4){
new Async5(activity).execute();
}
}
你暴露了很多变种。希望它们有用。
问候。