77
88#include < dlfcn.h>
99
10- std::string replace (const std::string &str, const std::string &from, const std::string &to)
10+ static std::string replace (const std::string &str, const std::string &from, const std::string &to)
1111{
1212 std::stringstream ss;
1313 size_t oldpos = 0 ;
@@ -29,17 +29,19 @@ std::string replace(const std::string &str, const std::string &from, const std::
2929 return ss.str ();
3030}
3131
32- jstring newStringUTF (JNIEnv *env, const std::string &str)
32+ static jstring newStringUTF (JNIEnv *env, const std::string &str)
3333{
34+ // We want std::string that contains null byte, hence length of 1.
3435 static std::string null (" " , 1 );
3536
3637 std::string newStr = replace (str, null, " \xC0\x80 " );
3738 jstring jstr = env->NewStringUTF (newStr.c_str ());
3839 return jstr;
3940}
4041
41- std::string getStringUTF (JNIEnv *env, jstring str)
42+ static std::string getStringUTF (JNIEnv *env, jstring str)
4243{
44+ // We want std::string that contains null byte, hence length of 1.
4345 static std::string null (" " , 1 );
4446
4547 const char *c = env->GetStringUTFChars (str, nullptr );
@@ -55,19 +57,27 @@ AndroidClient::AndroidClient()
5557{
5658 // Look for SDL_AndroidGetJNIEnv
5759 SDL_AndroidGetJNIEnv = (decltype (SDL_AndroidGetJNIEnv)) dlsym (RTLD_DEFAULT, " SDL_AndroidGetJNIEnv" );
60+ // Look for SDL_AndroidGetActivity
61+ SDL_AndroidGetActivity = (decltype (SDL_AndroidGetActivity)) dlsym (RTLD_DEFAULT, " SDL_AndroidGetActivity" );
5862}
5963
6064bool AndroidClient::valid () const
6165{
62- if (SDL_AndroidGetJNIEnv)
66+ if (SDL_AndroidGetJNIEnv && SDL_AndroidGetActivity )
6367 {
6468 JNIEnv *env = SDL_AndroidGetJNIEnv ();
6569
6670 if (env)
6771 {
68- jclass httpsClass = env->FindClass (" org/love2d/luahttps/LuaHTTPS" );
72+ jclass httpsClass = getHTTPSClass ();
73+ if (env->ExceptionCheck ())
74+ {
75+ env->ExceptionClear ();
76+ return false ;
77+ }
78+
6979 env->DeleteLocalRef (httpsClass);
70- return httpsClass != nullptr ;
80+ return true ;
7181 }
7282 }
7383
@@ -77,7 +87,7 @@ bool AndroidClient::valid() const
7787HTTPSClient::Reply AndroidClient::request (const HTTPSClient::Request &req)
7888{
7989 JNIEnv *env = SDL_AndroidGetJNIEnv ();
80- jclass httpsClass = env-> FindClass ( " org/love2d/luahttps/LuaHTTPS " );
90+ jclass httpsClass = getHTTPSClass ( );
8191
8292 if (httpsClass == nullptr )
8393 {
@@ -172,4 +182,31 @@ HTTPSClient::Reply AndroidClient::request(const HTTPSClient::Request &req)
172182 return response;
173183}
174184
185+ jclass AndroidClient::getHTTPSClass () const
186+ {
187+ JNIEnv *env = SDL_AndroidGetJNIEnv ();
188+
189+ jclass classLoaderClass = env->FindClass (" java/lang/ClassLoader" );
190+ jmethodID loadClass = env->GetMethodID (classLoaderClass, " loadClass" , " (Ljava/lang/String;)Ljava/lang/Class;" );
191+
192+ jobject activity = SDL_AndroidGetActivity ();
193+
194+ if (activity == nullptr )
195+ return nullptr ;
196+
197+ jclass gameActivity = env->GetObjectClass (activity);
198+ jmethodID getLoader = env->GetMethodID (gameActivity, " getClassLoader" , " ()Ljava/lang/ClassLoader;" );
199+ jobject classLoader = env->CallObjectMethod (activity, getLoader);
200+
201+ jstring httpsClassName = env->NewStringUTF (" org.love2d.luahttps.LuaHTTPS" );
202+ jclass httpsClass = (jclass) env->CallObjectMethod (classLoader, loadClass, httpsClassName);
203+
204+ env->DeleteLocalRef (gameActivity);
205+ env->DeleteLocalRef (httpsClassName);
206+ env->DeleteLocalRef (activity);
207+ env->DeleteLocalRef (classLoaderClass);
208+
209+ return httpsClass;
210+ }
211+
175212#endif
0 commit comments