/* Copyright 2012-2013, Polyvi Inc. (http://polyvi.github.io/openxface) This program is distributed under the terms of the GNU General Public License. This file is part of xFace. xFace is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. xFace is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with xFace. If not, see <http://www.gnu.org/licenses/>. */ package com.polyvi.xface; import java.io.IOException; import org.apache.cordova.CordovaActivity; import org.apache.cordova.CordovaChromeClient; import org.apache.cordova.CordovaInterface; import org.apache.cordova.CordovaWebView; import org.apache.cordova.CordovaWebViewClient; import android.app.Activity; import android.content.Context; import android.os.Build; import android.os.Bundle; import android.telephony.TelephonyManager; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.TextView; import com.polyvi.xface.app.XAppInfo; import com.polyvi.xface.app.XApplication; import com.polyvi.xface.app.XApplicationCreator; import com.polyvi.xface.app.XIApplication; import com.polyvi.xface.configXml.XTagNotFoundException; import com.polyvi.xface.core.XConfiguration; import com.polyvi.xface.core.XISystemContext; import com.polyvi.xface.event.XEvent; import com.polyvi.xface.event.XEventType; import com.polyvi.xface.event.XSystemEventCenter; import com.polyvi.xface.ssl.XSSLManager; import com.polyvi.xface.util.XConstant; import com.polyvi.xface.util.XLog; import com.polyvi.xface.util.XNotification; import com.polyvi.xface.util.XUtils; import com.polyvi.xface.view.XAppWebView; import com.polyvi.xface.view.XIceCreamWebViewClient; import com.polyvi.xface.view.XStartAppView; import com.polyvi.xface.view.XWebChromeClient; import com.polyvi.xface.view.XWebViewClient; /** * 该类是android程序的主activity,也是整个程序的入口. 主要管理整个程序的生命周期以及执行程序的初始化操作 */ public class XFaceMainActivity extends CordovaActivity implements XISystemContext { private static final String CLASS_NAME = XFaceMainActivity.class.getName(); private static final int ANDROID4_2_API_LEVEL = 17; protected TextView mVersionText; protected LinearLayout.LayoutParams mVersionParams; private XNotification mWaitingNotification = new XNotification(this);; private XStartParams mStartParams; private XSecurityPolicy mSecurityPolicy; /** App生成器 */ private XApplicationCreator mCreator; /** * 标示startapp */ private XApplication mStartApp; private XApplication mCurrentApp; private XSystemEventCenter mEventCenter; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); systemBoot(); } @Override public XSystemEventCenter getEventCenter() { return mEventCenter; } /** * 初始化startapp * * @param appInfo * startapp的信息 * @return */ public boolean initStartApp(XAppInfo appInfo) { XIApplication app = mCreator.create(appInfo); mStartApp = XApplicationCreator.toWebApp(app); return true; } private void setCurrentAppView(XAppWebView curAppView) { if (curAppView == null) { this.appView = null; this.webViewClient = null; return; } this.appView = curAppView; this.webViewClient = curAppView.getWebViewClient(); this.cancelLoadUrl = false; this.appView.requestFocus(); } @Override public XApplication getStartApp() { return mStartApp; } @Override protected CordovaWebView makeWebView() { XAppWebView webView = this.appView == null ? new XStartAppView(this) : new XAppWebView(this); mCurrentApp.setView(webView); return webView; } @Override protected CordovaWebViewClient makeWebViewClient(CordovaWebView webView) { CordovaWebViewClient webViewClient; if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB) { webViewClient = new XWebViewClient(this, webView); } else { webViewClient = new XIceCreamWebViewClient(this, webView); } return webViewClient; } @Override protected CordovaChromeClient makeChromeClient(CordovaWebView webView) { XWebChromeClient chrom = new XWebChromeClient(this, webView); webView.setWebChromeClient(chrom); return chrom; } public XApplicationCreator getAppFactory() { return mCreator; } @Override public Object onMessage(String id, Object data) { if ("exit".equals(id)) { XAppWebView xAppView = ((XAppWebView) appView); int viewId = xAppView.getViewId(); XEvent evt = XEvent.createEvent(XEventType.CLOSE_APP, viewId); mEventCenter.sendEventSync(evt); return true; } else if ("exit_engine".equals(id)) { endActivity(); return true; } return super.onMessage(id, data); } /** * 初始化系统事件处理器 */ private void initSystemEventCenter() { mEventCenter = new XSystemEventCenter(this); } /** * 创建app安全策略 * * @return 安全策略 */ protected XSecurityPolicy createSecurityPolicy() { return new XDefaultSecurityPolicy(this); } /** * 创建系统启动组件 * * @return */ protected XSystemBootstrap createSystemBootstrap() { return new XSystemInitializer(this); } /** * 创建管理与https有关证书库对象 */ protected void createSSLManager() { XSSLManager.createInstance(this); } /** * 程序的入口函数 */ private void systemBoot() { initSystemEventCenter(); mCreator = new XApplicationCreator(this); createSSLManager(); mSecurityPolicy = createSecurityPolicy(); XConfiguration.getInstance().loadPlatformStrings(getContext()); mStartParams = XStartParams.parse(getIntent().getStringExtra( XConstant.TAG_APP_START_PARAMS)); // 解析系统配置 try { initSystemConfig(); } catch (IOException e) { this.toast("Loading System Config Failure."); XLog.e(CLASS_NAME, "Loading system config failure!"); e.printStackTrace(); return; } catch (XTagNotFoundException e) { this.toast("Loading System Config Failure."); XLog.e(CLASS_NAME, "parse config.xml error:" + e.getMessage()); e.printStackTrace(); return; } // 启动splash startSplashScreen(); // 配置系统LOG等级 XLog.setLogLevel(XConfiguration.getInstance().readLogLevel()); // 配置系统的工作目录 XConfiguration.getInstance() .configWorkDirectory(this, getWorkDirName()); XSystemBootstrap bootstrap = createSystemBootstrap(); new XPrepareWorkEnvronmentTask(bootstrap).execute(); } /** * 开始splash操作 */ protected void startSplashScreen() { this.splashscreenTime = this.getIntegerProperty("SplashScreenDelay", this.splashscreenTime); if (this.splashscreenTime > 0) { this.splashscreen = this.getIntegerProperty("SplashScreen", 0); if (this.splashscreen != 0) { showSplashScreen(this.splashscreenTime); } } } @Override public void unloadView(XAppWebView view) { view.loadUrl("about:blank"); removeView(view); } /** * 解析系统配置 * * @throws IOException * @throws XTagNotFoundException */ private void initSystemConfig() throws IOException, XTagNotFoundException { XConfiguration.getInstance().readConfig(this); } /** * 获得手机的deviceId * * @return */ protected String getKey() { if (Build.VERSION.SDK_INT == ANDROID4_2_API_LEVEL) { return null; } TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); String deviceID = tm.getDeviceId(); return deviceID; } /** * 添加一个子视图到Activity的content view,如果view是可见的,则view会被显示在屏幕上 * * @param view * 子视图 */ public void addView(XAppWebView view) { if (view instanceof View) { View subView = (View) view; subView.setLayoutParams(new LinearLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 1.0F)); setCurrentAppView(view); root.addView(subView); } } @Override public XAppWebView getCurAppView() { return (XAppWebView) this.appView; } @Override public void loadView(XApplication app, String url) { mCurrentApp = app; if (this.appView != null) { this.init(); } loadUrl(url); } public void loadUrl(String url) { if (this.appView == null) { this.init(); } if (mCurrentApp.getAppInfo().getRunModeConfig().equals("online") && !XUtils.isOnline(this)) { mCurrentApp.clearCache(false); } super.loadUrl(url); } /** * 从Activity的content view中remove掉一个子视图 * * @param view * 子视图 */ public void removeView(XAppWebView view) { if (view instanceof View) { root.removeView((View) view); View pView = root.getChildAt(root.getChildCount() - 1); if (pView != null && pView instanceof XAppWebView) { XAppWebView pWebView = (XAppWebView) pView; setCurrentAppView(pWebView); } else { setCurrentAppView(null); } } } /** * 获取工作目录的名字 * * @return */ protected String getWorkDirName() { String packageName = getPackageName(); String workDir = XConfiguration.getInstance().getWorkDirectory(this, packageName) + XConstant.PRE_INSTALL_SOURCE_ROOT; return workDir; } @Override public void runStartApp() { getStartApp().start(getStartParams()); } @Override public void onDestroy() { super.onDestroy(); } @Override public Context getContext() { return this; } @Override public void toast(String message) { mWaitingNotification.toast(message); } @Override public XStartParams getStartParams() { return mStartParams; } @Override protected void showSplashScreen(int time) { if (splashDialog != null && splashDialog.isShowing()) { return; } super.showSplashScreen(time); } @Override public Activity getActivity() { return this; } @Override public XSecurityPolicy getSecurityPolicy() { return mSecurityPolicy; } @Override public CordovaInterface getCordovaInterface() { return this; } }