0

I am working on a Google Tango application and I have been trying to save an area description using the TangoApplication class.

I currently have the following function called on the OnApplicationPause() event

private void DoSaveCurrentAreaDescription(bool forceLearningMode)
{
    // Disable interaction before saving.
    m_initialized = false;
    if (m_tangoApplication.m_areaDescriptionLearningMode)
    {
        // The keyboard is not readable if you are not in the Unity main thread. Cache the value here.
        string name = "config";
        // Start saving process in another thread.

        m_saveThread = new Thread(delegate ()
        {
            // Start saving process in another thread.

            m_curAreaDescription = AreaDescription.SaveCurrent();
            AreaDescription.Metadata metadata = m_curAreaDescription.GetMetadata();
            metadata.m_name = name;
            m_curAreaDescription.SaveMetadata(metadata);
            m_TangoManager.m_lastKnownAreaDescription = m_curAreaDescription;
            m_TangoManager.SaveProductLocationsToDisk();

        });        

        m_saveThread.Start();

    }
    else
    {
        m_TangoManager.SaveProductLocationsToDisk();
    }
}

This gets called during the application pause function but it does not allow me to save the ADF. It will get saved, if I call this function while the app is still running.

If anyone has any idea what could be going on (i'm assuming is threading issues with the back-grounded process) I would be forever in your debt.

2 Answers2

1

It was actually due to the Tango life cycle pausing and unloading all of the Tango resources before my function on pause would have a chance to save it. There's not a real way to call that save area description function when going into the background currently. I've also contacted Google engineers and received a hefty "Don't Do That" because currently its not supported in the way that Tango works.

Tested on SDK: Hopak

0

There are two possible reasons why it it not saving:

1.Exception is thrown by Unity.

If the Tango AreaDescription or SaveProductLocationsToDisk API uses any Unity API then that's the problem because you can't use Unity API in another Thread and exception will be thrown if you try to do so.

You can check if this is the problem by putting the save code inside try catch block then view the result from Android Monitor in Android Studio.

The solution is to remove the Thread code and make sure the save code runs in the main Thread

private void DoSaveCurrentAreaDescription(bool forceLearningMode)
{
    // Disable interaction before saving.
    m_initialized = false;
    if (m_tangoApplication.m_areaDescriptionLearningMode)
    {
        //The keyboard is not readable if you are not in the Unity main thread. Cache the value here.
        string name = "config";
        //Start saving process in another thread.

        m_curAreaDescription = AreaDescription.SaveCurrent();
        AreaDescription.Metadata metadata = m_curAreaDescription.GetMetadata();
        metadata.m_name = name;
        m_curAreaDescription.SaveMetadata(metadata);
        m_TangoManager.m_lastKnownAreaDescription = m_curAreaDescription;
        m_TangoManager.SaveProductLocationsToDisk();
    }
    else
    {
        m_TangoManager.SaveProductLocationsToDisk();
    }
}

2.It's not saving because the app is exiting before it is done saving.

The solution is to add m_saveThread.Join(); to the end of the code so that Unity will wait for that code to execute before existing.

private void DoSaveCurrentAreaDescription(bool forceLearningMode)
{
    // Disable interaction before saving.
    m_initialized = false;
    if (m_tangoApplication.m_areaDescriptionLearningMode)
    {
        // The keyboard is not readable if you are not in the Unity main thread. Cache the value here.
        string name = "config";
        // Start saving process in another thread.

        m_saveThread = new Thread(delegate ()
        {
            // Start saving process in another thread.

            m_curAreaDescription = AreaDescription.SaveCurrent();
            AreaDescription.Metadata metadata = m_curAreaDescription.GetMetadata();
            metadata.m_name = name;
            m_curAreaDescription.SaveMetadata(metadata);
            m_TangoManager.m_lastKnownAreaDescription = m_curAreaDescription;
            m_TangoManager.SaveProductLocationsToDisk();

        });        

        m_saveThread.Start();
        //Wait for Save to finish before existing from app
        m_saveThread.Join();
    }
    else
    {
        m_TangoManager.SaveProductLocationsToDisk();
    }
} 

or again, remove the Thread code and make sure the save code runs in the main Thread like we did in #1.

Programmer
  • 121,791
  • 22
  • 236
  • 328