Working on trying to pass objects, unwrap them to C/C++ types, do something, then return the result as an object. Now I get why people say JNI is tricky

This commit is contained in:
amazing-username
2019-10-10 18:40:16 -04:00
parent 6b746cd1d0
commit 878c62f2cb
24 changed files with 337 additions and 843 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-3
View File
@@ -1,8 +1,5 @@
<component name="ProjectCodeStyleConfiguration"> <component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173"> <code_scheme name="Project" version="173">
<AndroidXmlCodeStyleSettings>
<option name="ARRANGEMENT_SETTINGS_MIGRATED_TO_191" value="true" />
</AndroidXmlCodeStyleSettings>
<JetCodeStyleSettings> <JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" /> <option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings> </JetCodeStyleSettings>
-3
View File
@@ -1,3 +0,0 @@
<component name="ProjectDictionaryState">
<dictionary name="phoenix" />
</component>
-4
View File
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
</project>
+1
View File
@@ -12,6 +12,7 @@
</set> </set>
</option> </option>
<option name="resolveModulePerSourceSet" value="false" /> <option name="resolveModulePerSourceSet" value="false" />
<option name="testRunner" value="PLATFORM" />
</GradleProjectSettings> </GradleProjectSettings>
</option> </option>
</component> </component>
-12
View File
@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="mear" external.linked.project.path="$MODULE_DIR$/../.." external.root.project.path="$MODULE_DIR$/../.." external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager">
<exclude-output />
<content url="file://$MODULE_DIR$/../..">
<excludeFolder url="file://$MODULE_DIR$/../../.gradle" />
<excludeFolder url="file://$MODULE_DIR$/../../build" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
-7
View File
@@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RenderSettings">
<option name="quality" value="0.0" />
<option name="showDecorations" value="true" />
</component>
</project>
Generated
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="VcsDirectoryMappings"> <component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" /> <mapping directory="" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/src/main/cpp/3rdparty/SQLiteCpp" vcs="Git" /> <mapping directory="$PROJECT_DIR$/app/src/main/cpp/3rdparty/SQLiteCpp" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/src/main/cpp/3rdparty/SQLiteCpp/googletest" vcs="Git" /> <mapping directory="$PROJECT_DIR$/app/src/main/cpp/3rdparty/SQLiteCpp/googletest" vcs="Git" />
<mapping directory="$PROJECT_DIR$/app/src/main/cpp/3rdparty/json" vcs="Git" /> <mapping directory="$PROJECT_DIR$/app/src/main/cpp/3rdparty/json" vcs="Git" />
+222 -798
View File
File diff suppressed because it is too large Load Diff
+40 -3
View File
@@ -251,7 +251,7 @@ Java_com_example_mear_activities_LoginActivity_retrieveSong(
extern "C" extern "C"
JNIEXPORT jobject JNIEXPORT jobject
JNICALL JNICALL
Java_com_example_mear_activities_LoginActivity_retrieveUserCredentials( Java_com_example_mear_repositories_UserRepository_retrieveUserCredentials(
JNIEnv *env, JNIEnv *env,
jobject thisObj, jobject thisObj,
jstring dataPath jstring dataPath
@@ -275,6 +275,43 @@ Java_com_example_mear_activities_LoginActivity_retrieveUserCredentials(
return userObj; return userObj;
} }
extern "C"
JNIEXPORT jobject
JNICALL
Java_com_example_mear_repositories_UserRepository_logUser(
JNIEnv *env,
jobject thisObj,
jobject user,
jstring apiUri ) {
jclass userClass = env->GetObjectClass(user);
//auto tok = env->CallObjectMethod(token, env->GetMethodID(tokenClass, "setAccessToken", "(Ljava/lang/String;)V"));
auto passwordField = env->GetFieldID(userClass, "getPassword", "(Ljava/lang/String;)V");
//auto passwordM = env->CallObjectMethod(user, env->GetMethodID(userClass, "password", "(Ljava/lang/String;)V"));
//auto passwordMOne = env->CallObjectMethod(user, env->GetMethodID(userClass, "getPassword", "(Ljava/lang/String;)V"));
auto password = env->GetObjectField(user, passwordField);
//auto username = env->CallObjectMethod(user, env->GetMethodID(userClass, "setUsername", "(Ljava/lang/String;)V"));
auto usernameField = env->GetFieldID(userClass, "setUsername", "(Ljava/lang/String;)V");
auto username = env->GetObjectField(user, usernameField);
const std::string usr = env->GetStringUTFChars((jstring)username, nullptr);
const std::string pass = env->GetStringUTFChars((jstring)password, nullptr);
const std::string api = env->GetStringUTFChars(apiUri, nullptr);
model::Token token(fetchToken(usr, pass, api));
jclass tokenClass = env->FindClass( "com/example/mear/models/Token");
jmethodID jconstructor = env->GetMethodID( tokenClass, "<init>", "()V" );
jobject tokenObj = env->NewObject( tokenClass, jconstructor );
jmethodID tokenAccess = env->GetMethodID( tokenClass, "setAccessToken", "(Ljava/lang/String;)V" );
jstring title = env->NewStringUTF(token.accessToken.c_str());
env->CallVoidMethod(tokenObj, tokenAccess, title);
return tokenObj;
}
extern "C" extern "C"
JNIEXPORT jstring JNIEXPORT jstring
@@ -299,7 +336,7 @@ Java_com_example_mear_activities_LoginActivity_logUser(
extern "C" extern "C"
JNIEXPORT jboolean JNIEXPORT jboolean
JNICALL JNICALL
Java_com_example_mear_activities_LoginActivity_isUserTableEmpty( Java_com_example_mear_repositories_UserRepository_isUserTableEmpty(
JNIEnv *env, JNIEnv *env,
jobject thisObj, jobject thisObj,
jstring dataPath jstring dataPath
@@ -313,7 +350,7 @@ Java_com_example_mear_activities_LoginActivity_isUserTableEmpty(
extern "C" extern "C"
JNIEXPORT jboolean JNIEXPORT jboolean
JNICALL JNICALL
Java_com_example_mear_activities_LoginActivity_doesDatabaseExist( Java_com_example_mear_repositories_BaseRepository_doesDatabaseExist(
JNIEnv *env, JNIEnv *env,
jobject thidObj, jobject thidObj,
jstring dataPath jstring dataPath
@@ -11,7 +11,9 @@ import kotlinx.android.synthetic.main.content_login.*
import org.jetbrains.anko.toast import org.jetbrains.anko.toast
import com.example.mear.models.Song import com.example.mear.models.Song
import com.example.mear.models.Token
import com.example.mear.models.User import com.example.mear.models.User
import com.example.mear.repositories.UserRepository
class LoginActivity : BaseServiceActivity() { class LoginActivity : BaseServiceActivity() {
@@ -24,12 +26,12 @@ class LoginActivity : BaseServiceActivity() {
private external fun retrieveSong(tok: String, api: String, songId: Int): Song private external fun retrieveSong(tok: String, api: String, songId: Int): Song
private external fun retrieveUserCredentials(path: String): User //private external fun retrieveUserCredentials(path: String): User
private external fun logUser(usr: String, pass: String, api: String): String private external fun logUser(usr: String, pass: String, api: String): String
private external fun doesDatabaseExist(path: String): Boolean //private external fun doesDatabaseExist(path: String): Boolean
private external fun isUserTableEmpty(path: String): Boolean //private external fun isUserTableEmpty(path: String): Boolean
private external fun pathIteratorDemo(path: String) private external fun pathIteratorDemo(path: String)
private external fun saveUserCredentials(username: String, password: String, appDir: String) private external fun saveUserCredentials(username: String, password: String, appDir: String)
@@ -41,8 +43,9 @@ class LoginActivity : BaseServiceActivity() {
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
val pa = appDirectory() val pa = appDirectory()
if (doesDatabaseExist(pa) && !isUserTableEmpty(pa)) { val usrRepo = UserRepository()
val usr = retrieveUserCredentials(pa) if (usrRepo.databaseExist(pa) && !usrRepo.isTableEmpty(pa)) {
val usr = usrRepo.retrieveCredentials(pa)
username.setText(usr.username) username.setText(usr.username)
password.setText(usr.password) password.setText(usr.password)
} }
@@ -71,22 +74,26 @@ class LoginActivity : BaseServiceActivity() {
val saveCred = saveUserCred.isChecked val saveCred = saveUserCred.isChecked
val usernameStr = username.text.toString()
val passwordStr = password.text.toString()
var apiUriStr = apiUri.text.toString() var apiUriStr = apiUri.text.toString()
val usr = User()
usr.username = username.text.toString()
usr.password = password.text.toString()
if (apiUriStr.isEmpty()) { if (apiUriStr.isEmpty()) {
apiUriStr = "" apiUriStr = "https://www.soaricarus.com"
} }
val token = logUser(usernameStr, passwordStr, apiUriStr) val myToken = Token(logUser(usr.username, usr.password, apiUriStr))
//val token = logUser(usernameStr, passwordStr, apiUriStr)
val usrRepo = UserRepository()
//val newToken = usrRepo.fetchToken(usr, apiUriStr)
try { try {
val songId = 4 val songId = 4
val song = retrieveSong(token, apiUriStr, songId) val song = retrieveSong(myToken.accessToken, apiUriStr, songId)
val pa = appDirectory() val pa = appDirectory()
if (saveCred && isUserTableEmpty(pa)) { if (saveCred && usrRepo.isTableEmpty(pa)) {
saveUserCredentials(usernameStr, passwordStr, pa) saveUserCredentials(usr.username, usr.password, pa)
} }
//startActivity(Intent(this, IcarusSongActivity::class.java)) //startActivity(Intent(this, IcarusSongActivity::class.java))
} }
@@ -0,0 +1,17 @@
package com.example.mear.repositories
open class BaseRepository {
companion object {
init {
System.loadLibrary("native-lib")
}
}
private external fun doesDatabaseExist(path: String): Boolean
fun databaseExist(path: String): Boolean {
return doesDatabaseExist(path)
}
}
@@ -0,0 +1,37 @@
package com.example.mear.repositories
import com.example.mear.models.Token
import com.example.mear.models.User
class UserRepository : BaseRepository() {
private external fun logUser(user: User, apiUri: String) : Token
private external fun retrieveUserCredentials(path: String) : User
private external fun isUserTableEmpty(path: String): Boolean
private external fun saveUserCredentials(username: User)
fun fetchToken(user: User, apiUri: String): Token {
val usr = logUser(user, apiUri)
return usr
}
fun retrieveCredentials(path: String): User {
return retrieveUserCredentials(path)
}
fun isTableEmpty(path: String): Boolean {
return isUserTableEmpty(path)
}
fun saveCredentials(user: User) {
saveUserCredentials(user)
}
}