上次说到Linphone-Android的入口类是LinphoneLauncherActivity
LinphoneLauncherActivity是在org.linphone下面的类,它的作用是判断linphone service是否ready,启动linphone 主activity
首先定义两个private变量:
private Handler mHandler;
private ServiceWaitThread mThread;
Handler是Android系统内置的类,而ServiceWaitThread是定义在LinphoneLauncherActivity类里面的私有类,该类的定义如下:
private class ServiceWaitThread extends Thread {
public void run() {
while (!LinphoneService.isReady()) {
try {
sleep(30);
} catch (InterruptedException e) {
throw new RuntimeException("waiting thread sleep() has been interrupted");
}
}
mHandler.post(new Runnable() {
@Override
public void run() {
onServiceReady();
}
});
mThread = null;
}
}
从以上代码可以看出,ServiceWaitThread是一个私有的线程类,该线程判断LinphoneService是否正常启动,如果启动则调用onServiceReady()方法. 这其中用到了Handler的post方法(将Runnable加入线程队列),作用是安排Runnable在主线程的某个地方执行,其实并没有真正实现异步操作。关于Handler的用法和意义见: 点击打开链接
下面来看看LinphoneLauncherActivity的两个方法: onCreate和onServiceReady
首先是onCreate方法:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Used to change for the lifetime of the app the name used to tag the logs
new Log(getResources().getString(R.string.app_name), !getResources().getBoolean(R.bool.disable_every_log));
// Hack to avoid to draw twice LinphoneActivity on tablets
// 通过isTablet BOOL变量判断是否是平板,如果是的话切换成横屏,如果不是则切换成竖屏
if (getResources().getBoolean(R.bool.isTablet)) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
} else {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
setContentView(R.layout.launcher);
mHandler = new Handler();
if (LinphoneService.isReady()) {
onServiceReady();
} else {
// start linphone as background
startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class));
mThread = new ServiceWaitThread();
mThread.start();
}
}
onCreate方法是Activity基类中的方法,目的是在该Activity创建的时候做一些初始化的工作
setContentView中将res/layout/launcher.xml布局文件加载进来:
然后判断Service是否已经起来,如果起来的话则执行onServiceReady, 如果没有,则通过startService启动LinphoneService并利用我们之前创建的ServiceWaitThread类等待service启动
再来看onServiceReady方法:
protected void onServiceReady() {
final Class<? extends Activity> classToStart;
if (getResources().getBoolean(R.bool.show_tutorials_instead_of_app)) {
classToStart = TutorialLauncherActivity.class;
} else if (getResources().getBoolean(R.bool.display_sms_remote_provisioning_activity) && LinphonePreferences.instance().isFirstRemoteProvisioning()) {
classToStart = RemoteProvisioningActivity.class;
} else {
classToStart = LinphoneActivity.class;
}
LinphoneService.instance().setActivityToLaunchOnIncomingReceived(classToStart);
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
startActivity(new Intent().setClass(LinphoneLauncherActivity.this, classToStart).setData(getIntent().getData()));
finish();
}
}, 1000);
}
通过设置不同的布尔值可以使主程序启动到不同的Activity上,然后使用startActivity启动相应的Activity类作为初始界面,一般来说如果没有特殊设置,会启动到LinphoneActivity这个Activity上。