IOS教程之我眼中的Qt for Android仓酷云
由于封闭文档写的相当好在遇到新框架的时候弄明白框架的功能去文档里搜搜框架的ProgrammingGuide很有用要弄明白框架类的继承结构写iOS的程序不一定都是用OBJC引子头几天,我分享了一下qtforandroid,从人人的反响和回馈,我看到两种极度的形态。一个是:“太好了!想做Android开辟可是不想转java,这下不必了!”另外一个是:“不要在Qt上华侈工夫了,它顶多在Android上跑个Helloworld,其余甚么也跑不了。”
我先说说我对QtforAndroid的客不雅熟悉。起首,从现有阶段看,不能不供认TA并非一个成熟的手艺(工具)。在年夜型项目中,仍是不倡议利用qtforandroid开辟的,由于材料太少,我们没法疾速深切的在年夜脑创建起qtforandroid收集,在碰到成绩的时分,办理起来就很辣手。可是,毫不是说仅仅就可以跑个Helloworld,假如真的这么一无可取,TA就没有存在的意义,也就不会吸引多量开辟者深切研讨和优化了。要晓得,世上最复杂的事变就是品评和痛斥。我再次夸大一下,我只是分享我所看到的晓得的,不带任何导游性。关于手艺自己,仁者见仁,智者见智。
咀嚼与探求
当我看到这么一个手艺工具,我的猎奇心使令我探求一下(1)TA究竟是怎样完成的,(2)程序在Android上实行效力和功能怎样,(3)较惯例的Androidjava开辟和jnic++开辟而言,二者之间有甚么能够互相自创,(4)倘使Google真的开放纯c++开辟,那末java和qtforandroid又是如何的一番风景?
一个开辟者分享他某一个程序的计划思绪:在Qt下经由过程jni失掉javaEnv,从而利用GPS等androidAPI,而且已完成:
[*]JNIEnv*currEnv;
[*]currEnv=0;
[*]if(currVM->AttachCurrentThread((void**)&currEnv,NULL)<0)
[*]{
[*]emiterror("CannotattachthecurrentthreadtotheVM");
[*]}
JNIEnv*currEnv;currEnv=0;if(currVM->AttachCurrentThread((void**)&currEnv,NULL)<0){emiterror("CannotattachthecurrentthreadtotheVM");}
大概由于我对Qt旌旗灯号和槽的情有独钟,看到emit就感应很亲热,而且被深深的吸引了。那末从Qtforandroid的qt工程源码看,究竟是怎样在android上乐成启动并运转的呢?
启动流程剖析
用qt-creator创立的每一个使用程序中,src下的文件都是基础不异。由于启动程序,创立接口,链接库,这些操纵是每一个使用程序所必须的,最后的qt程序被编译成了lib**.so的静态库,当挪用JNI接口startQtApp函数时真正启动了qt程序。
实行程序的出口在src/eu/licentia/necessitas/industrius/QtActivity.java中,onCreate挪用startapp反省需要的库文件,扩大包,插件是不是存在,并加载.链接ministro服务,得知ministro服务如今的形态,假如短少qt库则必要借助ministro服务下载。
privatevoidstartApp(finalbooleanfirstStart)
{
try
{
ActivityInfoai=getPackageManager().getActivityInfo(getComponentName(),PackageManager.GET_META_DATA);
if(!ai.metaData.containsKey("android.app.qt_libs_resource_id"))
{
//Norequiredqtlibs?
//Probablythisapplicationwascompiledusingstaticqtlibs
//orallqtlibsareprebundledintothepackage
m_ministroCallback.libs(null,null,null,0,null);
return;
}
intresourceId=ai.metaData.getInt("android.app.qt_libs_resource_id");
m_qtLibs=getResources().getStringArray(resourceId);
m_ministroCallback.libs(libs,"QT_IMPORT_PATH=/data/local/qt/imports QT_PLUGIN_PATH=/data/local/qt/plugins",
"-platform android",0,null);
return;
}
try{
if(!bindService(newIntent(eu.licentia.necessitas.ministro.IMinistro.class.getCanonicalName()),
m_ministroConnection,Context.BIND_AUTO_CREATE))
thrownewSecurityException("");
}catch(SecurityExceptione){}
}
使用程序必要的库由AndroidManifest.xml中的qt_libs_resource_id项指定,这一项来自于res/values/libs.xml中的qt_libs项。
[*]<?xmlversionxmlversion=1.0encoding=utf-8?>
[*]<resources>
[*]<arrayname="qt_libs">
[*]<item>QtCore</item>
[*]<item>QtGui</item>
[*]</array>
[*]<arraynamearrayname="bundled_libs"/>
[*]</resources>
[*]
<?xmlversion=1.0encoding=utf-8?><resources><arrayname="qt_libs"><item>QtCore</item><item>QtGui</item></array><arrayname="bundled_libs"/></resources>
qt使用程序的启动也是借助ministro服务,必要ministro供应响应的库撑持,当失掉响应的库后创立线程,启动startApplication。
privateIMinistroCallbackm_ministroCallback=newIMinistroCallback.Stub(){
@Override
publicvoidlibs(finalString[]libs,finalStringevnVars,finalStringparams,
interrorCode,StringerrorMessage)throwsRemoteException{
runOnUiThread(newRunnable(){
@Override
publicvoidrun(){
startApplication(libs,evnVars,params);
}
});
}
};
在src/eu/licentia/necessitas/industriusQtApplication.java中startApplication函数,先启动android的Plugin然后挪用一个JNI接口startQtApp启动qt程序。
QtActivity.java中的startApplication函数会挪用QtApplication.java中的startApplication。
publicstaticvoidstartApplication(Stringparams,Stringenvironment)
{
if(params==null)
params="-platform android";
synchronized(m_mainActivityMutex)
{
startQtAndroidPlugin();
setDisplayMetrics(m_displayMetricsScreenWidthPixels,
m_displayMetricsScreenHeightPixels,
m_displayMetricsDesktopWidthPixels,
m_displayMetricsDesktopHeightPixels,
m_displayMetricsXDpi,
m_displayMetricsYDpi);
if(params.length()>0)
params=" "+params;
startQtApp("QtApp"+params,environment);
m_started=true;
}
}
startQtApp时会启动线程startMainMethod,在startMainMethod线程中会将lib**.so中main函数出口以库函数接口的情势再次实行,恢复了qt可实行程序的原本脸孔,在背景实行
这部分源码在android-lighthouse的源码中。
JNI的部分代码
extern"C"intmain(int,char**);//usethestandardmainmethodtostarttheapplication
staticvoid*startMainMethod(void*/*data*/)
{
char**params;
params=(char**)malloc(sizeof(char*)*m_applicationParams.length());
for(inti=0;i<m_applicationParams.size();i++)
params=(char*)m_applicationParams.constData();
intret=main(m_applicationParams.length(),params);
......
}
重写onKeydown
经由过程上述挪用历程能够晓得,android程序是如何经由过程JNI来挪用qt库中的函数。其他相干android的的JNI接口在,plugins/platforms/android/下,好比keydown。
在src/eu/licentia/necessitas/industriusQtActivity.java重写了onKeydown函数,挪用JNI函数keyDown完成。
keyDown的完成在plugins/platforms/android/mw/androidjnimain.cpp中
staticvoidkeyDown(JNIEnv*/*env*/,jobject/*thiz*/,jintkey,jintunicode,jintmodifier)
{
……
intmappedKey=mapAndroidKey(key);
if(mappedKey==Qt::Key_Close)
{
qDebug()<<"handleCloseEvent"<<mLastTLW;
QWindowSystemInterface::handleCloseEvent(mLastTLW);
}
else
QWindowSystemInterface::handleKeyEvent(0,QEvent::KeyPress,mappedKey,modifiers,QChar(unicode),true);
//经由过程JNI的匡助,转化成了Qt的完成
}
停止语
先写到这吧,不论怎样说,打仗qtforandroid,让我劳绩了良多良多,相对不但限于qt和android范畴。
关于iOS开发的学习打个比方就像把汽车分解最底层的原料有塑料钢铁再用这些底层的工具造出来发动机座椅最后再加上写螺丝胶水等把汽车就拼起来了iOS基本都是英文的资料 要学会通过各种方法将面前的事情变成自己感兴趣的,那专研起来就不会是无聊和折磨了。 我也从简单的状态栏适配开始,先研究了下关于状态栏的适配,特总结如下,供广大网友一起讨论交流。 以上可以同时进行,学习过程中尽量不要纠结细节和底层,要知道ios是封闭的、OC是高级语言,我们不可能过多地去了解它的原理,至少在新手阶段没有必要。用迭代的方式更新你的知识,而不是死抠一个知识点。 特别是在校的学生,都存在一个小小的尴尬——虽然学习iOS开发的热情高涨,但由于没有多余的银子购买昂贵的Mac电脑而踟蹰不前。其实,针对初学者,如果想进入iOS开发的天地 在百度搜索你想要了解的类名(苹果的cocoa和cocoatouch框架的类名很有特点很容易搜到,前缀都是NS or UI),看别人写的博客详解 重要的是,放眼全球也的确找不到第二个如苹果iOS平台这样健壮、完整、先进而且为开发者带来真实收益的开发平台来。 在百度搜索你想要了解的类名(苹果的cocoa和cocoatouch框架的类名很有特点很容易搜到,前缀都是NS or UI),看别人写的博客详解 要学会通过各种方法将面前的事情变成自己感兴趣的,那专研起来就不会是无聊和折磨了。 培训时可以选择安卓,iOS,Java,因为实习的时候我选了安卓,当时实习时间只有三周,学的晕头转向,而java我也没学过,iOS的基础是C语言,这个大学里还是学过的,于是选择了iOS。 还有开发工具是用Xcode,是在Mac系统的,你多摸索一下就可以开发简单的应用了,建议你买一本iphone开发秘籍第二版看看,希望可以帮到你,谢谢。 AD: iPhone文件系统NSFileManager讲解是本文要介绍的内容,主要是通过iphone文件系统来学习NSFileManager的使用方法,具体内容来看本文详解。 自从苹果公司开放iOS SDK以来,大量的国内外的软件开发者将关注的目光聚集在苹果的iOS平台上。由于iPhone和iPad自一出现就给人带来了颠覆性的感觉 iPhone文件系统:创建、重命名以及删除文件,NSFileManager中包含了用来查询单词库目录、创建、重命名、删除目录以及获取/设置文件属性的方法(可读性,可编写性等等)。 从C语言入门,因为IOS开发用的是OC语言,是在C基础上的,不过也跟C不是很搭界,你可以直接学习OC语言也可以, AD: iPhone文件系统NSFileManager讲解是本文要介绍的内容,主要是通过iphone文件系统来学习NSFileManager的使用方法,具体内容来看本文详解。 众多研发人员积极参与到iOS平台的开发中来也就不足为奇了。 开始的时候甚至想放弃,不过想想自己的未来,只能咬牙坚持,课下就不停的缠着老师。放学就补基础,这些基础的东西没有速成的,只有刻苦努力。我是后来发现的,转变自己的心态,不要读书看资料当成一种痛苦 开始的时候甚至想放弃,不过想想自己的未来,只能咬牙坚持,课下就不停的缠着老师。放学就补基础,这些基础的东西没有速成的,只有刻苦努力。我是后来发现的,转变自己的心态,不要读书看资料当成一种痛苦 看《iPhone 4与iPad开发基础教程》,跟着一步步来
页:
[1]