Call native library method in independent native library
Its kind of unclear what you want the function to do, but If I understand, you want your Java-callable library to be like the following (assuming "C" not C++)
#include "zoom_Main_VideoPlayer.h"
#include <dlfcn.h>
void *handle;
typedef void (*func)(); // define function prototype
func myFunctionName; // some name for the function
JNIEXPORT void JNICALL Java_zoom_render_RenderView_naClose(JNIEnv *pEnv, jobject pObj) {
handle = dlopen("path to nativelibrary1.so", RTLD_LAZY);
myFunctionName = (func)dlsym(handle, "Close");
myFunctionName(); // passing parameters if needed in the call
dlclose(handle);
return;
}
And your other library will be:
// native method in nativelibrary1
void Close() {
if (!is) {
do_exit(is);
}
else {
do_exit(NULL);
}
LOGI(0, "Clean-up done");
}
Because your Close() does not have any arguments. You may also make your Java method static so that the spurious pObj isn't added to the native method signature.
If you described what the methods should do, I could make a better suggestion.
Load native library twice
OK, I found found a way to do it :) Maybe it is not a beautiful one, but it works fine:
Create a service:
import android.app.Service;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.IBinder;
public class rtmpdumpService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
config = this;
String extras = "";
if(intent != null){
//Get needed information
extras = intent.getExtras().getString("rtmp");
}
else {
this.stopSelf();
}
doWork(extras);
}
@Override
public void onDestroy() {
super.onDestroy();
}
public void doWork(String rtmp){
//Do work here: for example rtmpdump
Rtmpdump dump = new Rtmpdump();
dump.parseString(params[0]);
System.exit(0);
this.stopSelf();
}
}Register in AndroidManifest as service with these attributes
android:name=".rtmpdumpService"
android:exported="false"
android:process=":rtmp"Start service:
Intent rtmpdumpIntent = new Intent(getApplicationContext(), rtmpdumpService.class);
eSendIntent.putExtra("rtmp", "RTMP CODE");
startService(rtmpdumpIntent);
Sometimes you have to wait until it finishes:
After the Service is started (startService(rtmpdumpIntent):
do {
try {
Thread.sleep(500);
}
catch (InterruptedException e) {
//Log
}
} while( isServiceRunning(rtmpdumpService.class) == true);
isServiceRunning function:
private boolean isServiceRunning(Class cl) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (cl.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
Remove the instance of native library from app using dlclose(Android NDK)
try moving the position of the 'ReleaseString...'
it should be after the 'dlopen'
it should be before the call into the other shared lib...
(*env)->GetStringUTFChars
dlopen
(*env)->ReleaseStringUTFChars
make the main call
dlclose
Loading JNI library in another JNI library crashes
After using dlerror() to diagnose the problem, I actually found that dlopen was failing.
Turns the path was wrong. It should be:
handle = dlopen("/data/data/my.package/lib/myLibrary.so", RTLD_LAZY);
Android Studio error: Manifest merger failed: Apps targeting Android 12
You need to specify android:exported="false"
or android:exported="true"
Manifest:
<activity
android:name=".MainActivity"
android:exported="true"
android:theme="@style/Theme.MyApplication.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
as mentioned in the document:
If your app targets Android 12 and contains activities, services, or
broadcast receivers that use intent filters, you must explicitly
declare the android: exported attribute for these app components.
Warning: If an activity, service, or broadcast receiver uses intent
filters and doesn't have an explicitly-declared value for
android:exported, your app can't be installed on a device that runs
Android 12.
Also check when to use true/false for the 'android:exported' value.
Related Topics
Android Picasso Library, How to Add Authentication Headers
How to Take Multiple Photos Before Dismissing Camera Intent
Connect to Wifi in Android Q Programmatically
Failed to Resolve: Com.Github.Philjay:Mpandroidchart:V2.1.4
How to Play an Mp3 in the Res/Raw Folder of My Android App
How to Use Fragments in Android
Doze Mode and Foreground Service
Applying Word Stemming in Searchview for Fetch Data from Firebase Database
Put Buttons at Bottom of Screen with Linearlayout
Default Activity Not Found in Android Studio
Get the Distance Between Two Locations in Android
Uncaught Exception in Firebase Runloop (3.0.0)
How to Open Phones Gallery Through Code
Check If User Is Authenticated for the First Time in Firebase Google Authentication in Android
How to Correctly Start Activity from Postexecute in Android