Results 1 to 3 of 3

Thread: Qt Thread Issue with Android(?)

  1. #1
    Join Date
    Nov 2015
    Posts
    1
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Windows Android

    Default Qt Thread Issue with Android(?)

    Hello,
    I have been having an issue with my app crashing randomly, because of a problem in the QtThread.
    I am using Qt5.5 on QtCreator.

    The app is meant to run for an extended period of time (days to weeks) and at times it runs fine for days, and at others it crashes and fails.
    The error that is given by the application output is:

    F/libc ( 3353): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x4 in tid 3372 (QtThread)F/libc

    Unfortunately there is no surrounding output of code to give me any hints as to where/why this is happening. Also, because the crash is so seemingly random, I have no idea whether or not I have "fixed" it until it decides to crash again (or not).

    The app itself uses a bluetooth proximity sensor, and when it is triggered will show a selected screen. This screen could be a simple Calendar, whose data is read from Androids Calendar Provider.

    The only thing I can think of that would be causing this is the Calendar updating in the background causing a crash, or perhaps a Timer being called from the wrong thread.

    I have already investigated if timers are being jumbled through threads, and have read over KDABs explanation of how to access and use Android Java API from Qt on Android using JNI but since I am not using Intents or overriding any prewritten methods I am not entirely certain how/if this applies to my code.

    How my calendar is set up is I am querying a Google Calendar through AndroidCalendarClient.java,
    which is then called through an C++ AndroidCalendarClient class using QAndroidJNI,
    the C++ AndroidCalendarClient functions are then called from a calendarController C++ class and the results stored in a model or QStringList, which can be loaded and used through QML.
    (see below for source code bits)

    I have also looked through the Android Calendar Provider documentation, and it says under querying a calendar that the example shown is simplified and in practice should be called on an asynchronous thread. However, I'm not sure how to do this and whether it is required since I am calling it through Qt C++ anyways?

    This has gotten complicated, to summarize what I am asking is this:
    Am I looking in the right direction for this problem, or is there anything else you can think of that could be causing this?
    How would I make sure the Android and Qt threads are properly separated?
    Do I need to query the calendar on a separate asynchronous thread?

    Thank you very much, if there's anything else I can add or explain please let me know,

    spludlow

    Here are source code snippets showing the getCalendars() function (there is also a getEvents() function that works pretty much exactly the same way)
    AndroidCalendarClient.java
    Qt Code:
    1. import android.content.Context;
    2. import android.content.ContentProvider;
    3. import android.content.ContentResolver;
    4. import android.content.ContentUris;
    5. import android.content.ContentValues;
    6.  
    7. import android.database.Cursor;
    8.  
    9. import android.net.Uri;
    10.  
    11. import android.provider.CalendarContract;
    12. import android.provider.CalendarContract.Calendars;
    13. import android.provider.CalendarContract.Events;
    14. import android.provider.CalendarContract.Instances;
    15.  
    16. import java.util.ArrayList;
    17. import java.util.List;
    18. import java.util.Calendar;
    19. import java.util.Date;
    20.  
    21. public class AndroidCalendarClient {
    22.  
    23. //Projection array for Calendar. Creating indeices for this array instead of
    24. //dynamic lookups improves performance
    25. public static final String[] CALENDAR_PROJECTION = new String[] {
    26. Calendars._ID, // 0
    27. Calendars.ACCOUNT_NAME, // 1
    28. Calendars.CALENDAR_DISPLAY_NAME, // 2
    29. Calendars.OWNER_ACCOUNT // 3
    30. };
    31.  
    32. //The indices for the projection array above
    33. private static final int PROJECTION_ID_INDEX = 0;
    34. private static final int PROJECTION_ACCOUNT_NAME_INDEX = 1;
    35. private static final int PROJECTION_DISPLAY_NAME_INDEX = 2;
    36. private static final int PROJECTION_OWNER_ACCOUNT_INDEX = 3;
    37.  
    38. public static String[] getCalendars(Context context) {
    39. //System.out.println("AndroidCalendarClient.getCalendars() has been called");
    40. List<String> calendarList = new ArrayList<String>();
    41. try {
    42. // ...
    43. //run a query of the calendar
    44. Cursor curCal = null;
    45. ContentResolver cr = context.getContentResolver();
    46. Uri uri = Calendars.CONTENT_URI;
    47. //query all google calendars
    48. String selection = "((" + Calendars.ACCOUNT_TYPE +" = ? ))";
    49. String[] selectionArgs = new String[] {"com.google"};
    50.  
    51. // Submit the query and get a Cursor object back.
    52. curCal = cr.query(uri, CALENDAR_PROJECTION, selection, selectionArgs, null);
    53.  
    54. //Use the cursor to step through the returned records
    55. while (curCal.moveToNext()) {
    56. long calID = 0;
    57. String dispName = null;
    58.  
    59. //get the field values
    60. calID = curCal.getLong(PROJECTION_ID_INDEX);
    61. dispName = curCal.getString(PROJECTION_DISPLAY_NAME_INDEX);
    62.  
    63. //System.out.println("calID: "+calID+" displayName: "+dispName);
    64. //use CalendarEvent to hold details, title-> name, startTime-> calID
    65.  
    66. calendarList.add(dispName);
    67. }
    68. curCal.close();
    69. }catch (RuntimeException e) {
    70. e.printStackTrace();
    71. }
    72. return calendarList.toArray(new String[0]);
    73. }
    74. }
    To copy to clipboard, switch view to plain text mode 

    AndroidCalendarClient.cpp
    Qt Code:
    1. #include "AndroidCalendarClient.h"
    2.  
    3. #include <QApplication>
    4. #include <QDebug>
    5. #include <QtAndroidExtras/QAndroidJniEnvironment>
    6. #include <QtAndroidExtras/QAndroidJniObject>
    7. #include <qpa/qplatformnativeinterface.h>
    8.  
    9. AndroidCalendarClient::AndroidCalendarClient( QObject *parent) :
    10. CalendarClient(parent),
    11. m_context(0)
    12. {
    13. QPlatformNativeInterface * const interface = QApplication::platformNativeInterface();
    14. Q_ASSERT_X(interface, "AndroidCalendarClient", "Null pointer to QPlatformNativeInterface!");
    15. m_context = interface->nativeResourceForIntegration("QtActivity");
    16. Q_ASSERT_X(m_context, "AndroidCalendarClient", "Null pointer to void!");
    17. }
    18.  
    19. QList<QString> AndroidCalendarClient::getCalendar() {
    20. QList<QString> calendars;
    21. const QAndroidJniObject calObj = QAndroidJniObject::callStaticObjectMethod("org.qtproject.canassist.AndroidCalendarClient",
    22. "getCalendars",
    23. "(Landroid/content/Context;)[Ljava/lang/String;",
    24. m_context);
    25. if(calObj.isValid()) {
    26. const jobjectArray calendarArray = calObj.object<jobjectArray>();
    27. QAndroidJniEnvironment qjniEnv;
    28. const int n = qjniEnv->GetArrayLength(calendarArray);
    29. jclass clazz = 0;
    30.  
    31. for (int i = 0; i < n; i++){
    32. const jobject jCalendar = qjniEnv->GetObjectArrayElement(calendarArray, i);
    33. Q_ASSERT_X(jCalendar, "calendar", "Null jobject!");
    34. if(clazz == 0){
    35. clazz = qjniEnv->GetObjectClass(jCalendar);
    36. Q_ASSERT_X(clazz, "calendar", "Null jclass!");
    37. }
    38. else
    39. Q_ASSERT_X(qjniEnv->IsInstanceOf(jCalendar, clazz), "calendar", "jobject is not of the expected type!");
    40.  
    41. calendars.append(QAndroidJniObject(jCalendar).toString());
    42. qjniEnv->DeleteLocalRef(jCalendar);
    43. }
    44.  
    45. if (qjniEnv->ExceptionCheck()) {
    46. qjniEnv->ExceptionDescribe();
    47. Q_ASSERT(false);
    48. }
    49. }
    50. return calendars;
    51. }
    To copy to clipboard, switch view to plain text mode 

    calendarController.cpp
    Qt Code:
    1. void CalendarController::load() {
    2. qDebug() << "CalendarController::load()";
    3. g_rootContext->setContextProperty("CalendarController", this);
    4. QLOG_INFO() << "Loading Calendar. Valid: " <<g_rootContext->isValid();
    5. }
    6.  
    7. void CalendarController::loadCalendarModel() {
    8. Q_ASSERT_X(m_calendarClient, "loadCalendarModel", "Null pointer to CalendarClient!");
    9. QStringList model = QStringList()<<tr("No Calendar Selected");
    10.  
    11. foreach(QString calendar, m_calendarClient->getCalendar()) {
    12. model.append(calendar);
    13. }
    14. setCalendarModel(model);
    15. }
    16.  
    17. void CalendarController::setCalendarModel(QStringList model) {
    18. if(m_calendarModel != model){
    19. m_calendarModel = model;
    20. emit calendarModelChanged();
    21. }
    22. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    May 2009
    Location
    Canada
    Posts
    163
    Thanks
    7
    Thanked 20 Times in 20 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Windows Android

    Default Re: Qt Thread Issue with Android(?)

    Googling that error gives various possibilities: from running out of heap space due to large assets, to de-referencing a null pointer, to calling methods on the same object from different threads.

    My gut feeling is that this has to do with multiple threads, i.e., in which thread is your Bluetooth code called, and is that thread the same as the UI thread?

    The error that is given by the application output
    I think more information is needed than a seg fault message, to localize the problem. Contextualizing the error could be very useful for readers who are smarter than I am. What do you mean by application output? Do you mean in a log file? Are you are logging problems comprehensively? The reliance on Q_ASSERT_X, which of course doesn't even apply in release mode, suggests you are not.

    By the way, on what devices and versions of Android has this been observed?
    Last edited by Urthas; 11th November 2015 at 07:22.

  3. #3
    Join Date
    Apr 2011
    Posts
    31
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows Android

    Default Re: Qt Thread Issue with Android(?)

    Hello. I am working on Qt5 app with similar feature - it uses Calendar Content Provider to access events. Please let me know - what was the problem and was it solved?

    By the way - in my apps I met "suddenly asynchronous crashes" when I mixed UI Qt5 C++ code with QML views and Android Java functions. It always were not to be localized by simple code analysis. But I solved problem by manual using signal/slot QQueuedConnection-s between methods accessing to QML, C++ UI and C++ methods accessing Java functions. Direct connection forces receiving slot be executed in same thread as sending signal. Receiver cannot always be ready. But queued connection separates these threads and allows receiver process data when it is ready.
    Last edited by Gourmet; 6th August 2019 at 12:56.

Similar Threads

  1. Embedded resource issue - std::wstring on Windows vs. Android
    By d_stranz in forum Qt for Embedded and Mobile
    Replies: 0
    Last Post: 15th April 2015, 17:47
  2. Android Issue - webview moving left
    By ejoshva in forum Newbie
    Replies: 3
    Last Post: 10th April 2015, 21:04
  3. Qt/Android: Use QPainter in secondary thread.
    By kiozen in forum Qt for Embedded and Mobile
    Replies: 0
    Last Post: 27th January 2014, 13:02
  4. Replies: 1
    Last Post: 22nd September 2013, 13:40
  5. Necessitas Qt for Android issue
    By rickrvo in forum Qt for Embedded and Mobile
    Replies: 3
    Last Post: 8th June 2011, 10:30

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.