从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发布一次,然后打开项目目录进入AndroidDebugsplashScreenclasses
子目录,可以看到classes.dex 文件,这个就是delphi firemonkey在 android
在Dalvik中的基础支撑库了,接下来,我要使用一些工具来帮助我将java编写的activity合并到classes.dex中了;
拷贝java 工程中的src和res 到delphi xe5
的SplashScreen项目目录中,对照下图,别拷贝错位置了
先配置下系统环境变量
1. Android 我的是 C:Userscikkandroid-sdks
2. 配置System Path
Build-tools: 我的是 %ANDROID%build-tools19.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%platformsandroid-10"
set DX_LIB="%ANDROID%build-tools19.0.0lib"
set PROJ_DIR="�%"
set EMBO_DEX="D:Program FilesEmbarcaderoRAD
Studio12.0libandroiddebugclasses.dex"
set VERBOSE=0
mkdir outputclasses 2> nul
mkdir outputjar 2> nul
mkdir outputdex 2> nul
echo.
echo 编译 Java SplashActivity.java 源文件
echo.
SET VERBOSE_FLAG=-verbose
javac %VERBOSE_FLAG% -Xlint:deprecation -cp
%ANDROID_PLATFORM%android.jar -d outputclasses
srccomcikksplashsceenSplashActivity.java
echo.
echo 创建jar包
echo.
SET VERBOSE_FLAG=v
jar c%VERBOSE_FLAG%f outputjartest_classes.jar -C
outputclasses com
echo.
echo 转换为dex格式
echo.
SET VERBOSE_FLAG=--verbose
call dx --dex %VERBOSE_FLAG%
--output=%PROJ_DIR%outputdextest_classes.dex --positions=lines
%PROJ_DIR%outputjartest_classes.jar
echo.
echo 合并dex 文件
echo.
java -cp %DX_LIB%dx.jar com.android.dx.merge.DexMerger
%PROJ_DIR%outputdexclasses.dex
%PROJ_DIR%outputdextest_classes.dex %EMBO_DEX%
echo 删除临时文件
echo.
del outputdextest_classes.dex
del outputjartest_classes.jar
rmdir outputjar
echo.
echo 输出为 outputdexclasses.dex
:Exit
endlocal
如果批处理出现问题,请检测下环境变量的设置,还有注意EMBO_DEX的设置,对照你的xe5
安装路径重新设置下(前面我们发布管理中可以找到classes.dex的路径),成功执行批处理后,我们可以从项目目录
outputdex 中找到包含我们定义splashscreen的classes.dex
再次进入delphi 发布管理Project ->Deployment
确保缺省的classes.dex未被选中,点击Add Files
选择通过build生成的classes.dex,添加成功后选中新增项,点击Change Remote
Path,更改发布后的路径
将其它资源也纳入到发布路径中去
Reslayoutsplash_activity.xml
Resvaluesstrings.xml
Resdrawablesplash.png
点击保存,接下来我们要修改下delphi xe5 splashscreen 工程的配置文件
打开 splashscreen 工程目录下的AndroidManifest.template.xml
配置文件模板,加入java编写的activity 配置项;
android:name="com.cikk.splashsceen.SplashActivity"
android:screenOrientation="portrait">
/>
android:name="android.intent.category.LAUNCHER"
/>
将
android:name="com.embarcadero.firemonkey.FMXNativeActivity">
中的
/>
android:name="android.intent.category.LAUNCHER"
/>
删除,最后的我的配置文件如下
encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android"
package="%package%"
android:versionCode="%versionCode%"
android:versionName="%versionName%">
/>
android:persistent="%persistent%"
android:restoreAnyVersion="%restoreAnyVersion%"
android:label="%label%"
android:installLocation="%installLocation%"
android:debuggable="�buggable%"
android:icon="%icon%"
android:theme="%theme%">
android:name="com.cikk.splashsceen.SplashActivity"
android:screenOrientation="portrait">
/>
android:name="android.intent.category.LAUNCHER"
/>
android:name="com.embarcadero.firemonkey.FMXNativeActivity"
android:label="�tivityLabel%"
android:configChanges="orientation|keyboardHidden">
android:name="android.app.lib_name"
android:value="%libNameValue%" />
android:name="com.embarcadero.firemonkey.notifications.FMXNotificationAlarm"
/>
选好调试平台,调试运行一下吧,由于我是使用真机调试的,所以不好截图,我成功了,你们呢?
最后,通过这几天使用delphi平台,感觉做传统型数据库应用,应该够了,但相关资源相比较java来说太缺乏,如果要调用java的三方代码太繁琐,比如这个闪屏界面,不如直接使用java开发;我们选择开发平台时,应该多考虑下!
Cikk
2013/12/4