Qt on Android:使用JNI与第三方jar包
来源:互联网 发布:优酷视频下载器 mac 编辑:程序博客网 时间:2024/04/29 15:20
功能很简单,允许你输入一个web页面地址,使用Java的下载类库下载后用QTextEdit显示出来。
版权所有:foruok。转载请注明出处:http://blog.csdn.net/foruok。
效果展示
初始效果如图1所示:
图1 useJar示例初始效果
图2为点击"GET"按钮后下载到对应页面的效果:
图2 下载页面成功
下载部分,为了显示如何使用jar包,我用了asynchttpclient,参考我的博文:Android开源框架AsyncHttpClient (android-async-http)使用。
项目创建
参考《Qt on Android:图文详解Hello World全过程》吧,没什么特别可说的。
pro文件内添加“QT += androidextras”。
创建一个AndroidManifest,package命名为an.qt.useJar。
版权所有:foruok。转载请注明出处:http://blog.csdn.net/foruok。
添加Java源码
你可以任意的文本编辑器中编辑java源码,然后通过Qt Creator项目视图加到项目里,在其它文件那里鼠标右键点击,选择添加现有文件即可。参考下面几张图吧。
图3 添加Java源码之右键菜单
图4 添加Java源文件之选择Java源文件
图5 添加Java源文件OK
修改AndroidManifest,把activity标签的android:name属性值修改为an.qt.useJar.ExtendsQtWithJava。这是必须的,因为我们的ExtendsQtWithJava.java实现的Activity就是这个名字。
好了,Java代码添加结束。
添加第三方jar包
这个没什么好说的,放在android/libs目录下即可。看图:
图6 放jar包
只要放好位置,Qt Creator编译项目时就会把这个jar包打包到APK里。
Java源码使用jar包
这是java编程的内容了,import包名,然后使用即可。
源码分析
咱先看Java侧的代码吧。
Java代码
ExtendsQtWithJava.java:
- package an.qt.useJar;
- import java.lang.String;
- import android.content.Context;
- import android.content.Intent;
- import android.app.PendingIntent;
- import android.os.Handler;
- import android.os.Message;
- import android.util.Log;
- import android.net.ConnectivityManager;
- import android.net.NetworkInfo;
- import android.net.Uri;
- import android.location.Criteria;
- import android.provider.Settings;
- import android.os.Bundle;
- import android.os.Environment;
- import java.io.File;
- import com.loopj.android.http.AsyncHttpClient;
- import com.loopj.android.http.AsyncHttpResponseHandler;
- public class ExtendsQtWithJavaextends org.qtproject.qt5.android.bindings.QtActivity
- {
- private static ExtendsQtWithJava m_instance;
- private finalstatic String TAG = "extendsQt";
- private static String m_pageUri =null;
- private static Handler m_handler =new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case 1:
- if(m_pageUri == null){
- m_pageUri = (String)msg.obj;
- m_instance.downloadText(m_pageUri);
- }else{
- m_instance.notifyQt(0, (String)msg.obj,"Downloader is Busy now!");
- }
- break;
- };
- }
- };
- public ExtendsQtWithJava(){
- m_instance = this;
- }
- public staticint networkState(){
- ConnectivityManager conMan = (ConnectivityManager) m_instance.getSystemService(Context.CONNECTIVITY_SERVICE);
- return conMan.getActiveNetworkInfo() ==null ? 0 :1;
- }
- public static AsyncHttpClient m_httpc =new AsyncHttpClient();
- public static ExtendsQtNative m_nativeNotify =null;
- public void downloadText(String uri){
- Log.d(TAG, "start downloadText");
- m_httpc.get(uri, null, new AsyncHttpResponseHandler(){
- @Override
- public void onSuccess(String data){
- notifyQt(1, m_pageUri, data);
- m_pageUri = null;
- }
- @Override
- public void onFailure(Throwable e, String data){
- notifyQt(-1, m_pageUri, data);
- m_pageUri = null;
- }
- });
- }
- public staticvoid downloadWebPage(String uri){
- Log.d(TAG, "downloadWebPage");
- m_handler.sendMessage(m_handler.obtainMessage(1, uri));
- }
- private void notifyQt(int result, String uri, String data){
- if(m_nativeNotify == null){
- m_nativeNotify = new ExtendsQtNative();
- }
- m_nativeNotify.OnDownloaded(result, uri, data);
- }
- }
ExtendsQtNative.java:
- package an.qt.useJar;
- import java.lang.String;
- public class ExtendsQtNative
- {
- public nativevoid OnDownloaded(int result, String url, String content);
- }
基本思路是酱紫的:
Qt调用java的downloadWebPage,Java代码使用asynchttpclient下载一个网页,然后调用ExtendsQtNative通知Qt C++代码。
C++代码
分两部分,一部分是实现JNI方法。另一部分是调用Java类的方法。
实现JNI方法并注册
先看与ExtendsQtNative对应的JNI实现,在main.cpp中,都列出吧:
- #include "widget.h"
- #include <QApplication>
- #include <QAndroidJniEnvironment>
- #include <QAndroidJniObject>
- #include <jni.h>
- #include "../simpleCustomEvent.h"
- #include <QDebug>
- QObject *g_listener = 0;
- // result: -1 failed; 1 success; 0 busy;
- static void onDownloaded(JNIEnv *env, jobject thiz,int result, jstring uri, jstring data)
- {
- QString qstrData;
- const char *nativeString = env->GetStringUTFChars(data, 0);
- qstrData = nativeString;
- env->ReleaseStringUTFChars(data, nativeString);
- QCoreApplication::postEvent(g_listener, new SimpleCustomEvent(result, qstrData));
- }
- bool registerNativeMethods()
- {
- JNINativeMethod methods[] {
- {"OnDownloaded", "(ILjava/lang/String;Ljava/lang/String;)V", (void*)onDownloaded}
- };
- const char *classname ="an/qt/useJar/ExtendsQtNative";
- jclass clazz;
- QAndroidJniEnvironment env;
- QAndroidJniObject javaClass(classname);
- clazz = env->GetObjectClass(javaClass.object<jobject>());
- qDebug() << "find ExtendsQtNative - " << clazz;
- bool result = false;
- if(clazz)
- {
- jint ret = env->RegisterNatives(clazz,
- methods,
- sizeof(methods) / sizeof(methods[0]));
- env->DeleteLocalRef(clazz);
- qDebug() << "RegisterNatives return - " << ret;
- result = ret >= 0;
- }
- if(env->ExceptionCheck()) env->ExceptionClear();
- return result;
- }
- int main(int argc,char *argv[])
- {
- QApplication a(argc, argv);
- SimpleCustomEvent::eventType();
- registerNativeMethods();
- Widget w;
- g_listener = qobject_cast<QObject*>(&w);
- w.show();
- return a.exec();
- }
注册JNI方法,设置一个全局的对象接收通知。具体的,参考Qt帮助来理解。
调用Java方法
对Java方法的调用在Widget.cpp中。直接看代码吧。
widget.h:
- #ifndef WIDGET_H
- #define WIDGET_H
- #include <QWidget>
- #include <QLineEdit>
- #include <QTextEdit>
- #include <QLabel>
- class Widget : public QWidget
- {
- Q_OBJECT
- public:
- Widget(QWidget *parent = 0);
- ~Widget();
- bool event(QEvent *e);
- public slots:
- void onGet();
- private:
- QLineEdit * m_urlEdit;
- QTextEdit * m_resultView;
- QLabel * m_stateLabel;
- };
- #endif // WIDGET_H
都是界面相关的,没什么好说的。看widget.cpp:
- #include "widget.h"
- #include <QVBoxLayout>
- #include <QPushButton>
- #include "../simpleCustomEvent.h"
- #include <QAndroidJniObject>
- #include <QAndroidJniEnvironment>
- Widget::Widget(QWidget *parent)
- : QWidget(parent)
- {
- QVBoxLayout *layout = new QVBoxLayout(this);
- QHBoxLayout *getLayout = new QHBoxLayout();
- layout->addLayout(getLayout);
- m_urlEdit = new QLineEdit("http://blog.csdn.net/foruok");
- getLayout->addWidget(m_urlEdit, 1);
- QPushButton *getButton = new QPushButton("GET");
- getLayout->addWidget(getButton);
- connect(getButton, SIGNAL(clicked()), this, SLOT(onGet()));
- m_resultView = new QTextEdit();
- m_resultView->setReadOnly(true);
- layout->addWidget(m_resultView, 1);
- m_stateLabel = new QLabel();
- layout->addWidget(m_stateLabel);
- }
- Widget::~Widget()
- {
- }
- bool Widget::event(QEvent *e)
- {
- if(e->type() == SimpleCustomEvent::eventType())
- {
- e->accept();
- SimpleCustomEvent *sce = (SimpleCustomEvent*)e;
- switch(sce->m_arg1)
- {
- case 1:
- m_resultView->setText(sce->m_arg2);
- m_stateLabel->setText("Success!");
- break;
- case 0:
- m_resultView->setText(sce->m_arg2);
- m_stateLabel->setText("Failed!");
- break;
- case -1:
- m_stateLabel->setText(sce->m_arg2);
- break;
- }
- return true;
- }
- return QWidget::event(e);
- }
- void Widget::onGet()
- {
- #ifdef WIN32
- m_resultView->setText("Sorry, Just for Android!");
- #elif defined(ANDROID)
- QString url = m_urlEdit->text();
- QAndroidJniObject javaAction = QAndroidJniObject::fromString(url);
- QAndroidJniObject::callStaticMethod<void>("an/qt/useJar/ExtendsQtWithJava",
- "downloadWebPage",
- "(Ljava/lang/String;)V",
- javaAction.object<jstring>());
- m_stateLabel->setText("Downloading...");
- #endif
- }
调用Java的代码在onGet()槽中,很简单,不解释了。有疑问看Qt帮助手册有关QAndroidJniObject类的说明。
OK,到此结束。
版权所有:foruok。转载请注明出处:http://blog.csdn.net/foruok。
我的Qt on Android系列文章:
- Qt on Android:图文详解Hello World全过程
- Windows下Qt 5.2 for Android开发入门
- Qt for Android 部署流程分析
- Qt on Android:将Qt调试信息输出到logcat中
- Qt on Android: Qt 5.3.0 发布,针对 Android 改进说明
- Qt on Android Episode 1(翻译)
- Qt on Android Episode 2(翻译)
- Qt on Android Episode 3(翻译)
- Qt on Android Episode 4(翻译)
- Qt for Android 编译纯C工程
- Windows下Qt for Android 编译安卓C语言可执行程序
- Qt on Android: Android SDK安装
- Qt on Android: http下载与Json解析
- Qt on Android 之设置应用名为中文
- Qt on Android:让 Qt Widgets 和 Qt Quick 应用全屏显示
- Qt on Android:怎样适应不同的屏幕尺寸
- Qt on Android:使用JNI与第三方jar包
- Qt on Android:使用JNI与第三方jar包
- android 如何使用第三方jar包
- Android中使用第三方jar包
- C++项目通过JNI使用Java第三方jar包
- android jar 第三方包
- Android 第三方jar包
- 在android平台上使用第三方jar包
- Android平台如何使用第三方jar包文件
- 在Android应用中使用第三方Jar包
- android framework中添加使用第三方jar包
- android:使用Eclipse导出android项目jar包,包含第三方jar包
- java 环境变量与第三方jar包
- 打包第三方Jar包与Jre
- android 正确导入第三方jar包
- android导入第三方jar包
- android工程生成第三方jar包
- android引用第三方jar包
- SSH面试
- Pow(x, n)
- Win7 Java环境变量配置方法
- [HDU 4997 Biconnected] 无向图的边双联通子图计数 状压DP
- 进步的阶梯(1)---生成可执行jar包
- Qt on Android:使用JNI与第三方jar包
- wp8 application.resources 加入
- 【淘宝数据干货】我用数据告诉你互联网安全套行业是什么样的?【不看后悔!!!】
- Redmine 访问太缓慢--问题解决
- ajaxSubmit 上传成功 保存json文件 问题解决
- 你们说这样对吗?
- 我在网上收集的开源android app学习网址
- Jsoup总结
- 给大家说明。NHibernate:增删改