編輯:關於Android編程
很多朋友在論壇和QQ群裡問到這個,今天有時間寫了個簡單的示例。
功能很簡單,允許你輸入一個web頁面地址,使用Java的下載類庫下載後用QTextEdit顯示出來。
初始效果如圖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源碼,然後通過Qt Creator項目視圖加到項目裡,在其它文件那裡鼠標右鍵點擊,選擇添加現有文件即可。參考下面幾張圖吧。

圖3 添加Java源碼之右鍵菜單

圖4 添加Java源文件之選擇Java源文件

圖5 添加Java源文件OK
修改AndroidManifest,把activity標簽的android:name屬性值修改為an.qt.useJar.ExtendsQtWithJava。這是必須的,因為我們的ExtendsQtWithJava.java實現的Activity就是這個名字。
好了,Java代碼添加結束。
這個沒什麼好說的,放在android/libs目錄下即可。看圖:

圖6 放jar包
只要放好位置,Qt Creator編譯項目時就會把這個jar包打包到APK裡。
這是java編程的內容了,import包名,然後使用即可。
咱先看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 ExtendsQtWithJava extends org.qtproject.qt5.android.bindings.QtActivity
{
private static ExtendsQtWithJava m_instance;
private final static 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 static int 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 static void 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);
}
}
package an.qt.useJar;
import java.lang.String;
public class ExtendsQtNative
{
public native void OnDownloaded(int result, String url, String content);
}
Qt調用java的downloadWebPage,Java代碼使用asynchttpclient下載一個網頁,然後調用ExtendsQtNative通知Qt C++代碼。
分兩部分,一部分是實現JNI方法。另一部分是調用Java類的方法。
先看與ExtendsQtNative對應的JNI實現,在main.cpp中,都列出吧:
#include widget.h #include#include #include #include #include ../simpleCustomEvent.h #include 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 ()); 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 (&w); w.show(); return a.exec(); }
對Java方法的調用在Widget.cpp中。直接看代碼吧。
widget.h:
#ifndef WIDGET_H #define WIDGET_H #include#include #include #include 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
#include widget.h #include#include #include ../simpleCustomEvent.h #include #include 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 (an/qt/useJar/ExtendsQtWithJava, downloadWebPage, (Ljava/lang/String;)V, javaAction.object ()); m_stateLabel->setText(Downloading...); #endif }
OK,到此結束。
版權所有:foruok。轉載請注明出處:http://blog.csdn.net/foruok。
我的Qt on Android系列文章:
如何解決Android 手機耗電過快的方法
目前世界有幾十億安卓手機在使用,而大量Android 5.0用戶稱自己設備的耗電速度過快。原版Lollipop當中的確存在Wi-Fi引發的耗電問題,但谷歌已
Android 快速開發環境-Eclipse版(附完整資源)
對於很多新手來說,自己搭建一個開發環境的確不是一件容易的事;對於“老手”的開發者,搭建開發環境同樣也是一件麻煩的事,畢竟耗時費勁。但是,如果把相關
Android開發之ListView列表刷新和加載更多實現方法
本文實例講述了Android開發之ListView列表刷新和加載更多實現方法。分享給大家供大家參考。具體如下:上下拉實現刷新和加載更多的ListView,如下:packa
Android仿微信滑動退出Activity
效果圖:原理: 原理一句話就能描述清楚。重寫Activity的dispatchTouc