第二种方式主要思路暂时用于研究讨论,大概是,启动一条专门用于等待登陆结果的线程,在登陆的过程中处于挂起状态,在登陆有结果后由其它线程来唤醒该条等待线程,继续之前的工作。 写了个简单的类来实现上面的方式LogonRequireTask,仅是说明这种思路。 使用时类似于以下代码,直接使用execute方法执行你要做的事情,可以是跳转至个人信息页,可以是做收藏功能,这样的处理方式就很简单明了了。但是别忘记了在登陆逻辑完成时调用LogonRequireTask.loginEnded()
new LogonRequireTask() {
@Override
public boolean logon() {
return logon;//Utils.isLogin()
}
@Override
public void onLogout() {
// TODO Auto-generated method stub
}
}.execute(new Runnable() {
@Override
public void run() {
//when login ok,go on
//startActivity or do other things
}
});
建议将Runnable改成静态的,对context进行弱引用,防止产生内存问题。
下面是LogonRequireTask的全部代码,登陆RUNNING状态挂起线程,登陆完唤醒之。
package com.idroid.requirement;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import android.os.Handler;
public abstract class LogonRequireTask {
private static volatile Executor sDefaultExecutor = Executors
.newSingleThreadExecutor();
private final static int sDefaultWaitLong = 5 * 60 * 1000;
private static final Handler sHandler = new Handler();
private volatile Status mStatus = Status.IDLE;
public enum Status {
RUNNING, IDLE,
}
public abstract boolean logon();
/**
* 未登录时跳转至页
*/
public abstract void onLogout();
public static void loginEnded() {
synchronized (sHandler) {
sHandler.notifyAll();
}
}
public void setStatus(Status status) {
mStatus = status;
}
public final void execute(Runnable r) {
if (logon()) {
sHandler.post(r);
return;
}
if (mStatus != Status.RUNNING)
onLogout();
mStatus = Status.RUNNING;
final WorkerCallable callable = new WorkerCallable() {
@Override
public Boolean call() throws Exception {
if (logon())
return true;
if (mStatus == Status.IDLE)
return false;
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
synchronized (sHandler) {
sHandler.wait(sDefaultWaitLong);
mStatus = Status.IDLE;
return logon();
}
}
};
FutureTask<Boolean> future = new FutureTask<Boolean>(callable) {
@Override
protected void done() {
try {
final boolean result = get();
if (result) {
sHandler.post(callable.runnable);
} else {
sHandler.removeCallbacksAndMessages(null);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (NullPointerException e) {
e.printStackTrace();
}
}
};
callable.runnable = r;
sDefaultExecutor.execute(future);
}
private static abstract class WorkerCallable implements Callable<Boolean> {
Runnable runnable;
}
}