Text

Answered

What is the correct way to set the configuration again after making resource file dynamically.

What is the correct way to set the editor configuration , content package , content part  again after generating resource file dynamically.

Ex-  Set the configuration , content package ,content part. Now generate a custom resource file dynamically using "RecognitionAssetsBuilder" .

now what are the things are required to update like editor configuration, content package and content part , so that it will read our custom resource file.

Thanks & Regards


Best Answer

Dear Pankaj,


I was finally able to solve the issue you are facing.


Currently, what happens is that when you add a new word to your lexicon, you re-compile the myResource.res file, while it is still loaded in the RAM of your device.

When setting again the same configuration (conf.setString("text.configuration.name", "textconfiguration2");) we try to re-load in RAM a file which is still present. This causes the crash.


To solve it, when calling the add word, I set "textconfiguration1" (which releases the myResource.res file), then call saveWordToFileAndMakeResourceFile() and set again "textconfiguration2".


You can find this implementation in the following file: https://myscript.filecamp.com/s/q5s39RQovHi1Exet/d/jMKagPDWhXBpxsbY


Please note I did it into the "getstarted" instead of the "demo" (I recommend you use the getstarted instead of the demo, as it it simpler and is likely to better answer your needs).


Best regards,


Olivier


Dear Pankaj,

Currently, in order to set a configuration, this can be done either:
-at the engine level: https://developer.myscript.com/docs/interactive-ink/1.3/android/fundamentals/interactive-ink-runtime/#configuring-the-recognition
-or the editor level: https://developer.myscript.com/docs/interactive-ink/1.3/android/fundamentals/editing/#editor-level-configuration

In your case, when setting a new resource, I would recommend you set it at the editor level.

All you should normally need to do is set a part to the editor, the new resource should then be taken into account:
Configuration editorConfiguration = editor.getConfiguration();
editorConfiguration.setString("text.configuration.name", "myConf");
editor.setPart(contentPart);


You normally do not need to create a new engine or new contentPackage but can use the existing ones.

Let me know if this doesn't work.

Best regards,

Olivier

Hello Olivier,

Its not working . 

Code:

first i am  setting the  configuration as below; 

private void setTextConversionConfiguration{

Engine mEngine = AppController.getmEngine();
        Configuration conf = mEngine.getConfiguration();
        conf.setBoolean("text.guides.enable", false);
        conf.setString("text.configuration.bundle", "en_US");
        String confDir = "zip://" + mActivity.getPackageCodePath() 
         +"!/assets/conf";
        conf.setStringArray("configuration-manager.search-path", new String[]{confDir});
        String tempDir = mActivity.getFilesDir().getPath() + File.separator + "tmp";
        conf.setString("content-package.temp-folder", tempDir);
 DisplayMetrics displayMetrics = mActivity.getResources().getDisplayMetrics();
        Renderer renderer = mEngine.createRenderer(displayMetrics.xdpi, displayMetrics.ydpi, null);
        Map<String, Typeface> typefaceMap = new HashMap<>();
     Editor   mEditor = mEngine.createEditor(renderer);
        mEditor.setFontMetricsProvider(new FontMetricsProvider(displayMetrics, typefaceMap));

  String packageName = "myPackage.iink";
        File file = new File(Environment.getExternalStorageDirectory(), packageName);
        try { 
            mContentPackage = mEngine.createPackage(file);
            mContentPart = mContentPackage.createPart("Text"); 
            mEditor.setPart(mContentPart);
        } catch (Exception e) {
         e.toString();
        }

}

 now i generate resource file dynamically .

now if  i run the below code and the set the all configuration same by calling above method " setTextConversionConfiguration() " then the app get crash.

if (mContentPart != null) {
mContentPart.close();
mContentPart = null;
}
if (mContentPackage != null) {
mContentPackage.close();
mContentPackage = null;
}
mEditor.setPart(null);

Thanks & Regards

Pankaj Tyagi

Dear Pankaj,


Currently, I do not see anything wrong in the setTextConversionConfiguration function. Do you have an error message or the logs? This willl help.


Regardibg disposing the objects, you are not doing it the proper order. You should rather proceed as follows:

mEditor.waitForIdle();
mEditor.setPart(null);
mEditor.setFontMetricsProvider(null);
mEditor.close();
mEditor = null;

if (mContentPart != null) {
mContentPart.close();
mContentPart = null;
}
if (mContentPackage != null) {
mContentPackage.close();
mContentPackage = null;
}

Best regards,

Olivier

Hello Olivier ,

I don't have any logs .

But my app is still crashing after updating .

Regards,

Pankaj Tyagi

Dear Pankaj Tyagi,



We recommand you setting the configuration on the editor.

If we assume that your package is alreay opened and contains a single part and that you want to update dynamically your text configuration on your editor, the sequence would be:



   if (contentPart != null)
    {
      contentPart.close();
      contentPart = null;
    }
    contentPart = contentPackage.getPart(0);

    if (contentPart != null)
    {
      contentPart.close();
      contentPart = null;
    }

    editor.setPart(null);
    editor.clear();

    Configuration conf = editor.getConfiguration();
    conf.setString("text.configuration.name", "customResource");

    contentPart = contentPackage.createPart("Text");

    editor.setPart(contentPart);




Regards,


Gwenaëlle

Hello Gwenaëlle,

I applied changes suggested by you but now I am getting " Configuration resource not found " error in " onError() " Callback method of "IEditorListener", and app is still crashing.

Regards

Pankaj Tyagi

Dear Pankaj,


thank you for the update.


This error means the iink is not able to find your new configuration in your conf file.


Can you please provide your configuration file and the way you call your configuration?


Thank you,


Best regards,


Olivier

Hello Olivier,

Configuration file code:

 en_US.conf file 

Bundle-Version: 1.0
Bundle-Name: en_US
Configuration-Script:
 AddResDir /data/user/0/com.sample.example/app_example_directory

Name: text
Type: Text
Configuration-Script:
 AddResource en_US-ak-cur.res
 AddResource en_US-lk-text.res
 AddResource myResource.res
 AddResource en_US-lk-grm.res
 EnableAlienCharacters
 SetTextListSize 1
 SetWordListSize 7
 SetCharListSize 1 

  Code which we are using on app launch.    

private void setTextConversionConfiguration{

Engine mEngine = AppController.getmEngine();
        Configuration conf = mEngine.getConfiguration();
        conf.setBoolean("text.guides.enable", false);
        conf.setString("text.configuration.bundle", "en_US");
        String confDir = "zip://" + mActivity.getPackageCodePath() 
         +"!/assets/conf";
        conf.setStringArray("configuration-manager.search-path", new String[]{confDir});
        String tempDir = mActivity.getFilesDir().getPath() + File.separator + "tmp";
        conf.setString("content-package.temp-folder", tempDir);
 DisplayMetrics displayMetrics = mActivity.getResources().getDisplayMetrics();
        Renderer renderer = mEngine.createRenderer(displayMetrics.xdpi, displayMetrics.ydpi, null);
        Map<String, Typeface> typefaceMap = new HashMap<>();
     Editor   mEditor = mEngine.createEditor(renderer);
        mEditor.setFontMetricsProvider(new FontMetricsProvider(displayMetrics, typefaceMap));

  String packageName = "myPackage.iink";
        File file = new File(Environment.getExternalStorageDirectory(), packageName);
        try { 
            mContentPackage = mEngine.createPackage(file);
            mContentPart = mContentPackage.createPart("Text"); 
            mEditor.setPart(mContentPart);
        } catch (Exception e) {
         e.toString();
        }

}

   Code which we use after adding any word to resource file.  

private void setConfigurationAfterAddingNewWord(){

if (mContentPart != null) {
            mContentPart.close();
            mContentPart = null;
        }
        mContentPart = mContentPackage.getPart(0);

        if (mContentPart != null) {
            mContentPart.close();
            mContentPart = null;
        }

        mEditor.setPart(null);
        mEditor.clear();

        Configuration conf = mEditor.getConfiguration();
        conf.setString("text.configuration.name", "myResource.res");

        mContentPart = mContentPackage.createPart("Text");

        mEditor.setPart(mContentPart);
}

   Regards

Pankaj Tyagi

Dear Pankaj,

thank you for the update.

Currently, let me explain how you shall proceed.

The configuration file shall be defined as follows:
Bundle-Version: 1.0
Bundle-Name: en_US
Configuration-Script:
AddResDir /data/user/0/com.sample.example/app_example_directory

Name: configuration1
Type: Text
Configuration-Script:
AddResource en_US-ak-cur.res
AddResource en_US-lk-text.res
EnableAlienCharacters
SetTextListSize 1
SetWordListSize 7
SetCharListSize 1

Name: configuration2
Type: Text
Configuration-Script:
AddResource en_US-ak-cur.res
AddResource en_US-lk-text.res
AddResource myResource.res
EnableAlienCharacters
SetTextListSize 1
SetWordListSize 7
SetCharListSize 1


First, ensure ALL the resources are properly deployed into the "AddResDir" directory (resp. /data/user/0/com.sample.example/app_example_directory)
In order to call the "configuration1", in your code, you shall call it as follows: conf.setString("text.configuration.name", "configuration1");

In your case, as you want to call a custom "myResource.res", I recommend you create a second configuration, as in the above example, and then call it as follows: conf.setString("text.configuration.name", "configuration2");

Last, I noticed you were adding at the same time the grm resource (en_US-lk-grm.res) and the text resource (en_US-lk-text.res) ; as the text resource already contains a grm, I recommend you do not add it into your configuration.

Last, please note than when no configuration is set, by default it will try to load the "text" configuration.

Let us know if this helps.

Best regards,

Olivier

Hello Olivier,

We applied changes suggested by you but our app is still crashing.

We modified the Sample App provided by MyScript with your suggested changes to support another resource file.

Sample app also crashed after making changes. 

Following are the changes, which we have done in the Sample App :

  1. We have modified Demo module of the Sample app.
  2. We have added code to add new words from options menu.
  3. Generated resource file etc in MainActivity.java
  4. Whenever we add a new word, we create resource file, and set configurations.

After performing step 4, we observed two types of crashes.

 Below are the crash logs of first crash:

 java.lang.IllegalStateException: com.myscript.iink.ContentPackage closed
        at com.myscript.iink.ContentPackage.checkNotClosed(ContentPackage.java:49)
        at com.myscript.iink.ContentPackage.createPart(ContentPackage.java:156)
        at com.myscript.iink.demo.MainActivity.setConfiguration(MainActivity.java:594)
        at com.myscript.iink.demo.MainActivity$4.onClick(MainActivity.java:246)
        at android.view.View.performClick(View.java:5265)
        at android.view.View$PerformClick.run(View.java:21534)
        at android.os.Handler.handleCallback(Handler.java:815)
        at android.os.Handler.dispatchMessage(Handler.java:104)
        at android.os.Looper.loop(Looper.java:207)
        at android.app.ActivityThread.main(ActivityThread.java:5728)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)

This crash can be fixed by commenting below code :

if (documentController.currentPackage != null) {
            documentController.currentPackage.close();
            documentController.currentPart = null;
        }

But if we comment above lines, we face another crash. This is not always reproducible, but it has a frequency of almost 4/10.

Below are the crash logs:  

07-19 11:23:12.045 5087-5087/com.myscript.iink.demo A/libc: Fatal signal 6 (SIGABRT), code -6 in tid 5087 (cript.iink.demo)
07-19 11:23:12.189 5173-5173/? A/AEE/DEBUG:     #04 pc 00000000000215e0  /system/lib64/libc.so (__libc_fatal+128)


Modified sample app code can be found at below link :

https://github.com/pankajTyagi92/myTextConversion 

 

Regards,

Pankaj Tyagi

Dear Pankaj,


thanks to your project, I was able to reproduce.


I keep investigating, and update you within few days.


Best regards,


Olivier


Answer

Dear Pankaj,


I was finally able to solve the issue you are facing.


Currently, what happens is that when you add a new word to your lexicon, you re-compile the myResource.res file, while it is still loaded in the RAM of your device.

When setting again the same configuration (conf.setString("text.configuration.name", "textconfiguration2");) we try to re-load in RAM a file which is still present. This causes the crash.


To solve it, when calling the add word, I set "textconfiguration1" (which releases the myResource.res file), then call saveWordToFileAndMakeResourceFile() and set again "textconfiguration2".


You can find this implementation in the following file: https://myscript.filecamp.com/s/q5s39RQovHi1Exet/d/jMKagPDWhXBpxsbY


Please note I did it into the "getstarted" instead of the "demo" (I recommend you use the getstarted instead of the demo, as it it simpler and is likely to better answer your needs).


Best regards,


Olivier

  • Support
  • Forums
  • Text
  • What is the correct way to set the configuration again after making resource file dynamically.