QT androidextras getMemoryInfo memoryInfo availmem对象字段从C 崩



如何从C QT 5.6 Android拨打GetMemoryInfo?我不确定在调用GetSystemservice API时从Java/Lang/Object铸造到Android/App/ActivationManager,但我得到有效的qandroidjniobject btw。这是我到目前为止的代码。

osinfoandroid.h

#ifndef OSINFOANDROID_H
#define OSINFOANDROID_H
#include <QObject>
class OsInfoAndroid : public QObject {
    Q_OBJECT
public:
explicit OsInfoAndroid(QObject *parent = 0);
~OsInfoAndroid();
public Q_SLOTS:
void testgetmeminfo();
};
#endif  // OSINFOANDROID_H

osinfoandroid.cpp

#include "osinfoandroid.h"
#include <QDebug>
#include <QtAndroidExtras/QtAndroidExtras>
OsInfoAndroid::OsInfoAndroid(QObject *parent) : QObject(parent) {}
OsInfoAndroid::~OsInfoAndroid() {}
void OsInfoAndroid::testgetmeminfo() {
QAndroidJniObject cntact_service = QAndroidJniObject::getStaticObjectField(
  "android/content/Context", "ACTIVITY_SERVICE", "Ljava/lang/String;");
if (cntact_service.isValid()) {
qDebug() << Q_FUNC_INFO << "ACTIVITY_SERVICE OK GOT INTERNAL STRING";
} else {
    qDebug() << Q_FUNC_INFO << "ACTIVITY_SERVICE sad got nothing :(";
}
QAndroidJniObject ctx = QtAndroid::androidActivity().callObjectMethod(
  "getApplicationContext", "()Landroid/content/Context;");
if (ctx.isValid()) {
qDebug() << Q_FUNC_INFO << "got valid context";
} else {
    qDebug() << Q_FUNC_INFO << "sad got nothing context";
}
QAndroidJniObject actmgr = ctx.callObjectMethod(
  "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;",
  cntact_service.object<jstring>());
if (actmgr.isValid()) {
qDebug() << Q_FUNC_INFO << "ok got ActivityManager";
QAndroidJniObject meminfo("android/app/ActivityManager$MemoryInfo");
if(!meminfo.isValid ()){
    qDebug()<<Q_FUNC_INFO<<"SAD GOT INVALID MemoryInfo!";
    return;
}
qDebug()<<Q_FUNC_INFO<<"ok got valid MemoryInfo";
//CRASH HERE
QAndroidJniObject voidmeminfo = actmgr.callObjectMethod(
    "getMemoryInfo", "(Landroid/app/ActivityManager$MemoryInfo;)V",
    meminfo.object<jclass>());
    if (voidmeminfo.isValid()) {
  qDebug() << Q_FUNC_INFO << "OK CALLING getMemoryInfo FROM CPP SUKSES!! ";
    } else {
  qDebug() << Q_FUNC_INFO << "calling from c++ failed!!";
    }
 }
}

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <osinfoandroid.h>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
OsInfoAndroid osinfo;
engine.rootContext ()->setContextProperty ("osinfo",&osinfo);
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
}

androidmanifest.xml

<?xml version="1.0"?>
<manifest package="org.androidgetmeminfocrash" xmlns:android="http://schemas.android.com/apk/res/android" android:versionName="1.0" android:versionCode="1" android:installLocation="auto">
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --">
    <activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:label="-- %%INSERT_APP_NAME%% --" android:screenOrientation="unspecified" android:launchMode="singleTop">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
        <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
        <meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
        <meta-data android:name="android.app.repository" android:value="default"/>
        <meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
        <meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
        <!-- Deploy Qt libs as part of package -->
        <meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
        <meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
        <meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
        <!-- Run with local libs -->
        <meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
        <meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
        <meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
        <meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
        <meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
        <!--  Messages maps -->
        <meta-data android:value="@string/ministro_not_found_msg" android:name="android.app.ministro_not_found_msg"/>
        <meta-data android:value="@string/ministro_needed_msg" android:name="android.app.ministro_needed_msg"/>
        <meta-data android:value="@string/fatal_error_msg" android:name="android.app.fatal_error_msg"/>
        <!--  Messages maps -->
        <!-- Splash screen -->
        <!--
        <meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/>
        -->
        <!-- Splash screen -->
        <!-- Background running -->
        <!-- Warning: changing this value to true may cause unexpected crashes if the
                      application still try to draw after
                      "applicationStateChanged(Qt::ApplicationSuspended)"
                      signal is sent! -->
        <meta-data android:name="android.app.background_running" android:value="false"/>
        <!-- Background running -->
        <!-- auto screen scale factor -->
        <meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/>
        <!-- auto screen scale factor -->
    </activity>
</application>
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="14"/>
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
     Remove the comment if you do not require these default permissions. -->
<!-- %%INSERT_PERMISSIONS -->
<!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
     Remove the comment if you do not require these default features. -->
<!-- %%INSERT_FEATURES -->
<uses-permission android:name="android.permission.GET_TASKS"/>
    <uses-permission android:name="android.permission.HARDWARE_TEST"/>
</manifest>

整个项目可以在此处下载

好吧,这个问题看起来像是从这里打电话

QAndroidJniObject voidmeminfo = actmgr.callObjectMethod(
    "getMemoryInfo", "(Landroid/app/ActivityManager$MemoryInfo;)V",
    meminfo.object<jclass>());

可以更改为

actmgr.callMethod<void>(
    "getMemoryInfo", "(Landroid/app/ActivityManager$MemoryInfo;)V",
    meminfo.object<jobject>());

但是我不确定哪个是正确的,无论使用meminfo.Object&lt;jobject>());或meminfo.Object&lt;jclass>());

所以,我想获取Android MemoryInfo availmem对象字段,在调用getMemoryInfo函数后,我添加此代码

QAndroidJniObject availmem=meminfo.getObjectField("availMem","J");
if(!availmem.isValid ()){
   qDebug() << Q_FUNC_INFO << "calling from c++ failed!!";
}

但是,上面的代码仍会在Android Jelly Bean上产生明显的崩溃,任何指针?

我想实现的等价Java代码是这样的

ActivityManager activityManager = (ActivityManager)     context.getSystemService(ACTIVITY_SERVICE);
MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
activityManager.getMemoryInfo(memoryInfo);
Log.i(TAG, " memoryInfo.availMem " + memoryInfo.availMem + "n" );

现在,我正在使用基于上述项目源下载的全Java主体功能的第二种方法。尝试从C 发出有效的活动上下文,并在Java中调用普通静态方法。然后创建文件夹com-> getmemorycrash文件夹。然后我创建一个Java文件Osinfo.java,所以现在我的getMemoryinfo.pro变得像这样

QT += qml quick androidextras
CONFIG += c++11
SOURCES += main.cpp osinfoandroid.cpp
HEADERS +=  osinfoandroid.h
RESOURCES += qml.qrc
# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
DISTFILES += 
    android/AndroidManifest.xml 
    android/gradle/wrapper/gradle-wrapper.jar 
    android/gradlew 
    android/res/values/libs.xml 
    android/build.gradle 
    android/gradle/wrapper/gradle-wrapper.properties 
    android/gradlew.bat 
    android/src/com/getmemorycrash/OsInfo.java
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android

osinfo.java

package com.getmemorycrash;
import java.lang.Object;
import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import java.lang.String;
import android.content.Context;
import android.util.Log;
public class OsInfo {
 static long getMemavail(Context context ){
    Log.d("ada","executing getMemavail");
    ActivityManager activityManager = (ActivityManager)     context.getSystemService(Context.ACTIVITY_SERVICE);
    MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
    activityManager.getMemoryInfo(memoryInfo);
    Log.i("mydebug", " memoryInfo.availMem " + memoryInfo.availMem + "n" );
    return memoryInfo.availMem;
 }
}

最终的osinfoandroid.cpp,我添加了testgetmeminfomethod2函数,并以下代码

void OsInfoAndroid::testgetmeminfomethod2()
{
QAndroidJniObject ctx = QtAndroid::androidActivity().callObjectMethod(
    "getApplicationContext", "()Landroid/content/Context;");
if (ctx.isValid()) {
  qDebug() << Q_FUNC_INFO << "got valid context";
} else {
  qDebug() << Q_FUNC_INFO << "sad got nothing context";
}
//crash here
QAndroidJniObject availmem=QAndroidJniObject::callStaticObjectMethod("com/getmemorycrash/OsInfo",
                                                                     "getMemavail",
                                                                     "(Landroid/content/Context;)J",
                                                                     ctx.object<jclass>());
if(!availmem.isValid ()){
      qDebug() << Q_FUNC_INFO << "calling from c++ failed!!";
 }  
}

那么,我的问题是为什么以上函数再次变成segfault?执行Java代码直到log android函数和然后立即发生崩溃,完全在返回时发生?

谢谢

好吧,我最终可以修复此问题,如果它们是原始类型的公共成员Java类变量的正确函数,我可以使用上述情况使用第一种方法而不是中继来基于上述情况在qandroidjniobject上

jlong availmem=meminfo.getField<jlong>("availMem");

相关内容

  • 没有找到相关文章

最新更新