从embarcadero官方技术论坛找了下参考资料,对黑屏处理应该来说有了相应的办法,并且这种办法具有很好的应用价值,因此做了个总结,Delphi XE5 无黑屏从本质上讲是使用Android 原生开发语言java ,编写的程序启动时首先加载java编写的SplashScreen 的activity,然后在splashScreenActivity中启动delphi FireMonkey中的com.embarcadero.firemonkey.FMXNativeActivity; 首先新建立一个移动端项目,启动Rad studio xe5,File -> New ->FireMonkey Mobile Application,拖上一个TLabel 控件作为演示,保存项目 设置Android SDK 我使用的Android SDK 22.0.5 32bit 版本,对应平台为2.35,如果你是其它SDK版本,可以右键点击 SDK,选择 Edit SDK进行配置 Build一下当前项目,然后打开当前项目下AndroidManifest.template.xml文件 将其中android:largeHeap="%largeHeap%" 去掉,否则发布会报错(我不太清楚是否是特点Android版本问题,或者有无其它参数进行设置,反正我就是这样解决的),好了,Demo先放在这里,我们接着要建立一个java for android 下的启动Activity项目,这里得用eclipse + ADT进行开发 建立Android Application Project,建立Android Activity ,命名为SplashActivity,注意包 命名空间,我的命名空间是com.cikk.splashsceen,简单的设置一下View 接下来编写SplashActivity的代码,我们要做的是SplashActivity启动后延时3秒,3秒结束后启动com.embarcadero.firemonkey.FMXNativeActivity 这个Delphi Xe5 for android 下的这个特定Activity,代码如下 package com.cikk.splashsceen; import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.util.Log; import android.view.Window; import android.view.WindowManager; public class SplashActivity extends Activity { private boolean active = true; private static int SPLASH_TIME_OUT = 3000; private static int SPLASH_INTERVAL = 100; int get_resource_id(String resourceName, String resourceType) { return this.getResources().getIdentifier(resourceName, resourceType, this.getPackageName()) ; } int get_string_id(String resourceName) { return get_resource_id(resourceName, "string"); } int get_drawable_id(String resourceName) { return get_resource_id(resourceName, "drawable"); } int get_layout_id(String resourceName) { return get_resource_id(resourceName, "layout"); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(get_layout_id("splash_activity")); new Thread(new Runnable() { @Override public void run() { try { int elapsed = 0; while (SplashActivity.this.active && (elapsed < SPLASH_TIME_OUT)) { Thread.sleep(SPLASH_INTERVAL); if (SplashActivity.this.active) elapsed += SPLASH_INTERVAL; } } catch (InterruptedException e) { } finally { finish(); if (SplashActivity.this.active) { Intent launchIntent = new Intent(); Log.d("Splash", "Launching the main activity now"); launchIntent.setClassName(SplashActivity.this, "com.embarcadero.firemonkey.FMXNativeActivity"); startActivity(launchIntent); } } } }).start(); } } 启动调试一下,三秒钟就自动退出了 回到Delphi XE5,我们将SplashScreen 工程Build一次,然后点击Project ->Deployment 进入发布管理模块 点击Deploy发布一次,然后打开项目目录进入Android\Debug\splashScreen\classes 子目录,可以看到classes.dex 文件,这个就是delphi firemonkey在 android 在Dalvik中的基础支撑库了,接下来,我要使用一些工具来帮助我将java编写的activity合并到classes.dex中了; 拷贝java 工程中的src和res 到delphi xe5 的SplashScreen项目目录中,对照下图,别拷贝错位置了 先配置下系统环境变量 1. Android 我的是 C:\Users\cikk\android-sdks 2. 配置System Path Build-tools: 我的是 %ANDROID%\build-tools\19.0.0 3. 检查JDK 的 bin 目录是否在System Path 中,建议使用jdk1.6,我曾经使用1.7,但由于版本问题,无法成功合并到classes.dex中; 经过配置,打开命令提示窗口运行javac;jar;dx 确保命令能够正确执行; 在delphi xe5 的SplashScreen项目目录中编写Build.bat 批处理 批处理内容如下 @echo on setlocal set ANDROID_PLATFORM="%ANDROID%\platforms\android-10" set DX_LIB="%ANDROID%\build-tools\19.0.0\lib" set PROJ_DIR="?%" set EMBO_DEX="D:\Program Files\Embarcadero\RAD Studio\12.0\lib\android\debug\classes.dex" set VERBOSE=0 mkdir output\classes 2> nul mkdir output\jar 2> nul mkdir output\dex 2> nul echo. echo 编译 Java SplashActivity.java 源文件 echo. SET VERBOSE_FLAG=-verbose javac %VERBOSE_FLAG% -Xlint:deprecation -cp %ANDROID_PLATFORM%\android.jar -d output\classes src\com\cikk\splashsceen\SplashActivity.java echo. echo 创建jar包 echo. SET VERBOSE_FLAG=v jar c%VERBOSE_FLAG%f output\jar\test_classes.jar -C output\classes com echo. echo 转换为dex格式 echo. SET VERBOSE_FLAG=--verbose call dx --dex %VERBOSE_FLAG% --output=%PROJ_DIR%\output\dex\test_classes.dex --positions=lines %PROJ_DIR%\output\jar\test_classes.jar echo. echo 合并dex 文件 echo. java -cp %DX_LIB%\dx.jar com.android.dx.merge.DexMerger %PROJ_DIR%\output\dex\classes.dex %PROJ_DIR%\output\dex\test_classes.dex %EMBO_DEX% echo 删除临时文件 echo. del output\dex\test_classes.dex del output\jar\test_classes.jar rmdir output\jar echo. echo 输出为 output\dex\classes.dex :Exit endlocal 如果批处理出现问题,请检测下环境变量的设置,还有注意EMBO_DEX的设置,对照你的xe5 安装路径重新设置下(前面我们发布管理中可以找到classes.dex的路径),成功执行批处理后,我们可以从项目目录output\dex 中找到包含我们定义splashscreen的classes.dex 再次进入delphi 发布管理Project ->Deployment 确保缺省的classes.dex未被选中,点击Add Files 选择通过build生成的classes.dex,添加成功后选中新增项,点击Change Remote Path,更改发布后的路径 将其它资源也纳入到发布路径中去 Res\layout\splash_activity.xml Res\values\strings.xml Res\drawable\splash.png 点击保存,接下来我们要修改下delphi xe5 splashscreen 工程的配置文件 打开 splashscreen 工程目录下的AndroidManifest.template.xml 配置文件模板,加入java编写的activity 配置项; <activity android:name="com.cikk.splashsceen.SplashActivity" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> 将<activity android:name="com.embarcadero.firemonkey.FMXNativeActivity"> 中的 <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> 删除,最后的我的配置文件如下 <?xml version="1.0" encoding="utf-8"?> <!-- BEGIN_INCLUDE(manifest) --> <manifest xmlns:android="http://schemas./apk/res/android" package="%package%" android:versionCode="%versionCode%" android:versionName="%versionName%"> <!-- This is the platform API where NativeActivity was introduced. --> <uses-sdk android:minSdkVersion="%minSdkVersion%" /> <%uses-permission%> <application android:persistent="%persistent%" android:restoreAnyVersion="%restoreAnyVersion%" android:label="%label%" android:installLocation="%installLocation%" android:debuggable="?buggable%" android:icon="%icon%" android:theme="%theme%"> <activity android:name="com.cikk.splashsceen.SplashActivity" android:screenOrientation="portrait"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- Our activity is a subclass of the built-in NativeActivity framework class. This will take care of integrating with our NDK code. --> <activity android:name="com.embarcadero.firemonkey.FMXNativeActivity" android:label="?tivityLabel%" android:configChanges="orientation|keyboardHidden"> <!-- Tell NativeActivity the name of our .so --> <meta-data android:name="android.app.lib_name" android:value="%libNameValue%" /> </activity> <receiver android:name="com.embarcadero.firemonkey.notifications.FMXNotificationAlarm" /> </application> </manifest> <!-- END_INCLUDE(manifest) --> 选好调试平台,调试运行一下吧,由于我是使用真机调试的,所以不好截图,我成功了,你们呢? 最后,通过这几天使用delphi平台,感觉做传统型数据库应用,应该够了,但相关资源相比较java来说太缺乏,如果要调用java的三方代码太繁琐,比如这个闪屏界面,不如直接使用java开发;我们选择开发平台时,应该多考虑下! Cikk 2013/12/4 |
|