Recall CallBack(); function when need to use - android

How can I call my CallBack() again when I need to use it?
Currently, I'm calling my CallBack() by doing this
CallBackThreadHome callBackThreadHome = new CallBackThreadHome();
callBackThreadHome.start();
Correct me if I'm wrong, but It will eat my RAM consumption?.Because I'm getting a Fatal Error Fatal signal 11 (SIGSEGV) at 0x0000000b (code=1), thread 2347 (i.mikee.jti_pos) .Our device only has 1 GB of RAM that's why I'm very careful on the Threading side.
This is the callBackThreadHome();
class CallBackThreadHome extends Thread {
#Override
public void run() {
try {
RFCardInterface.waitForCardPresent(RFCardInterface.CONTACTLESS_CARD_MODE_AUTO, 1, -1);
if (RFCardInterface.isCallBackCalled &&
RFCardInterface.notifyEvent.eventID == RFCardInterface.CONTACTLESS_CARD_EVENT_FOUND_CARD) {
IDCatcher = StringUtility.ByteArrayToString(RFCardInterface.notifyEvent.eventData,
RFCardInterface.notifyEvent.eventData.length);
IDCatcher = IDCatcher.substring(9, 21);
IDCatcher = IDCatcher.replace(" ", "");
Cursor c = dbhelper.getReadableDatabase().rawQuery("select is_arrived,is_closed from trans_settings order by _id desc limit 1", null);
if (c != null && c.moveToFirst()) {
String is_arrived = c.getString(0);
String is_closed = c.getString(1);
if (is_arrived.equals("0") && is_closed.equals("0")) {
SearchEmp();
} else if (is_arrived.equals("1") && is_closed.equals("0")) {
SearchEmp_isArrived();
} else if (is_arrived.equals("1") && is_closed.equals("1")) {
SearchEmp_isClosed();
}
c.close();
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
}
browsing on Android Studio, There has a function callBackThreadHome.run(). Isn't it appropriate?.

Just save the "CallBackThreadHome" in a Global variable and you can reuse it whenever you want.
RAM "eating" doesn't depends of Threading system but only of the WORK you do INSIDE it, however callback doesn't means "Multithreading" but just a method that is called at some specific time from another piece of code.
The SIGSEGV error has a specific meaning, but it's another story/question.

Related

OnPartialResult (Speechrecognition capacitor)

I am having a problem understanding how to change the OnPartialResults function inside of the android code (in speechrecognition) to only return the new work every time a word is detected instead of the whole array of words
For example if i am saying (test) the result returned while session is remaining active is [test] but if i then proceed to say (test) again the returned result (onpartial) is now including the word found earlier [test, test], and i am only needing it to return the newly found word.
Current code
#Override
public void onPartialResults(Bundle partialResults) {
ArrayList<String> matches = partialResults.getStringArrayList(
SpeechRecognizer.RESULTS_RECOGNITION
);
JSArray matchesJSON = new JSArray(matches);
try {
if (
matches != null &&
matches.size() > 0 &&
!previousPartialResults.equals(matchesJSON)
) {
previousPartialResults = matchesJSON;
}
} catch (Exception ex) {}
}

Most elegant way to log when early return (quite common when defensive programming)?

When doing defensive programming, I often have some early-return code. In addition, I need to write some log warning that the function returns because of what problem.
void f(A a) {
var b = a.b;
if (b == null) {
Log.warn('f skip running since b==null');
return;
}
var c = some_func(b);
if (c == null) {
Log.warn('f skip running since c==null');
return;
}
another_func(c);
}
I know I can use null-aware operators like ?. but it cannot print warnings when it is null.
I have also tried another approach:
void f(A a) {
var errorMessage = fCore(a);
if (errorMessage!=null) Log.warn(errorMessage);
}
String fCore(A a) {
var b = a.b;
if (b == null) {
return 'f skip running since b==null';
}
var c = some_func(b);
if (c == null) {
return 'f skip running since c==null';
}
another_func(c);
return null
}
But that is also kind of verbose.
Is there a better approach? Thanks!
EDIT
I call it like:
void outer_func() {
one_func();
f(); // even if f skip running, I want two_func still run, etc
two_func();
...
}
Thus, I cannot simply do something like throw LogWarnException('...') and catch at outermost function.

android.renderscript.RSRuntimeException Fatal error 4097

I'm getting the following crash from renderscript on android:
100% of the crashes are on android 11 and 96% of the crashes are on Samsung devices. I removed all instances of renderscript, but this crash is still happening so maybe it's in one of my dependencies.
I found this got android.renderscript.RSRuntimeException on note4 which says that 4097 means a fatal driver error, but doesn't give any details on how to fix it.
Does anyone know how I can fix this crash?
UPDATE: when I search for "renderscript" in my app nothing comes up unless I put it on scope and then there's a bunch of references to it. I don't understand where they're coming from though
UPDATE: To be clear, I have removed all references to renderscript from my app but it seems like one or multiple of my dependencies are still using it. I need help isolating these dependencies. Something called android-30 is using renderscript. Is this the api 30 library or something? And then something called support/v8 is using renderscript. Is this the support library? (I do have support library enabled)
Migrate from RenderScript
RenderScript APIs are deprecated starting in Android 12. They will
continue to function, but we expect that device and component
manufacturers will stop providing hardware acceleration support over
time.
It seems to be a vendors issue (Driver issue)
Fatal error 4097: RS_ERROR_FATAL_UNKNOWN = 0x1000
static class MessageThread extends Thread {
RenderScript mRS;
boolean mRun = true;
int[] mAuxData = new int[2];
static final int RS_MESSAGE_TO_CLIENT_NONE = 0;
static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1;
static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2;
static final int RS_MESSAGE_TO_CLIENT_ERROR = 3;
static final int RS_MESSAGE_TO_CLIENT_USER = 4;
static final int RS_MESSAGE_TO_CLIENT_NEW_BUFFER = 5;
static final int RS_ERROR_FATAL_DEBUG = 0x0800;
static final int RS_ERROR_FATAL_UNKNOWN = 0x1000;
MessageThread(RenderScript rs) {
super("RSMessageThread");
mRS = rs;
}
public void run() {
// This function is a temporary solution. The final solution will
// used typed allocations where the message id is the type indicator.
int[] rbuf = new int[16];
mRS.nContextInitToClient(mRS.mContext);
while(mRun) {
rbuf[0] = 0;
int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData);
int size = mAuxData[1];
int subID = mAuxData[0];
if (msg == RS_MESSAGE_TO_CLIENT_USER) {
if ((size>>2) >= rbuf.length) {
rbuf = new int[(size + 3) >> 2];
}
if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
RS_MESSAGE_TO_CLIENT_USER) {
throw new RSDriverException("Error processing message from RenderScript.");
}
if(mRS.mMessageCallback != null) {
mRS.mMessageCallback.mData = rbuf;
mRS.mMessageCallback.mID = subID;
mRS.mMessageCallback.mLength = size;
mRS.mMessageCallback.run();
} else {
throw new RSInvalidStateException("Received a message from the script with no message handler installed.");
}
continue;
}
if (msg == RS_MESSAGE_TO_CLIENT_ERROR) {
String e = mRS.nContextGetErrorMessage(mRS.mContext);
// Throw RSRuntimeException under the following conditions:
//
// 1) It is an unknown fatal error.
// 2) It is a debug fatal error, and we are not in a
// debug context.
// 3) It is a debug fatal error, and we do not have an
// error callback.
if (subID >= RS_ERROR_FATAL_UNKNOWN ||
(subID >= RS_ERROR_FATAL_DEBUG &&
(mRS.mContextType != ContextType.DEBUG ||
mRS.mErrorCallback == null))) {
throw new RSRuntimeException("Fatal error " + subID + ", details: " + e);
}
if(mRS.mErrorCallback != null) {
mRS.mErrorCallback.mErrorMessage = e;
mRS.mErrorCallback.mErrorNum = subID;
mRS.mErrorCallback.run();
} else {
android.util.Log.e(LOG_TAG, "non fatal RS error, " + e);
// Do not throw here. In these cases, we do not have
// a fatal error.
}
continue;
}
if (msg == RS_MESSAGE_TO_CLIENT_NEW_BUFFER) {
if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
RS_MESSAGE_TO_CLIENT_NEW_BUFFER) {
throw new RSDriverException("Error processing message from RenderScript.");
}
long bufferID = ((long)rbuf[1] << 32L) + ((long)rbuf[0] & 0xffffffffL);
Allocation.sendBufferNotification(bufferID);
continue;
}
// 2: teardown.
// But we want to avoid starving other threads during
// teardown by yielding until the next line in the destructor
// can execute to set mRun = false
try {
sleep(1, 0);
} catch(InterruptedException e) {
}
}
//Log.d(LOG_TAG, "MessageThread exiting.");
}
}

PjSIP Callling it from unknown/external thread

I'm trying to build pjsip and make a basic phone call by building a cordova plugin in Android. The following function is in a cordova plugin named
public class PJSIP extends CordovaPlugin{ .... }
private void makeCall(String number,String hostip ) {
String buddy_uri = "sip:"+number+"#"+hostip;
MyAccount account = null;
AccountConfig accCfg = null;
accCfg = new AccountConfig();
accCfg.setIdUri("sip:localhost");
accCfg.getNatConfig().setIceEnabled(true);
accCfg.getVideoConfig().setAutoTransmitOutgoing(true);
accCfg.getVideoConfig().setAutoShowIncoming(true);
MyAccount acc = new MyAccount(accCfg);
account = acc;
MyCall call = new MyCall(account, -1);
CallOpParam prm = new CallOpParam(true);
try {
call.makeCall(buddy_uri, prm);
} catch (Exception e) {
call.delete();
return;
}
currentCall = call;
}
What I receive as an error is the following:
A/libc: ../src/pj/os_core_unix.c:692: pj_thread_this: assertion
"!"Calling pjlib from unknown/external thread. You must " "register
external threads with pj_thread_register() " "before calling any pjlib
functions."" failed
I was checking around and it seems that there is an issue with the garbage collector but I'm not sure how to fix it.
Thanks
In pjsip, every call must come from a thread known to pjsip.
On your EndPoint object there is a method that helps you with that.
Basically, I just created a static method checkThread which helps me registering the currentThread.
I call this method at the beginning of every method that accesses pjsip objects.
You need to synchronize this method.
public static synchronized void checkThread() {
try {
if (mEndpoint != null && !mEndpoint.libIsThreadRegistered())
mEndpoint.libRegisterThread(Thread.currentThread().getName());
} catch (Exception e) {
Log.w("SIP", "Threading: libRegisterThread failed: " + e.getMessage());
}
}
And now each of your methods that access sip objects has to look like:
public void makeCall(String number) {
checkThread();
//...do your stuff...
}
Hope this helps, Cheers.

How can I detect the Android runtime (Dalvik or ART)?

Google added a new ART runtime with Android 4.4. How can I determine whether ART or Dalvik is the current runtime?
Update
At least, as early as June 2014 Google has released an official documentation on how to correctly verify the current runtime in use:
You can verify which runtime is in use by calling System.getProperty("java.vm.version"). If ART is in use, the property's value is "2.0.0" or higher.
With that, now there is no need to go through reflection and simply check the corresponding system property:
private boolean getIsArtInUse() {
final String vmVersion = System.getProperty("java.vm.version");
return vmVersion != null && vmVersion.startsWith("2");
}
One possible way is to read the respective SystemProperty through reflection.
Sample:
package com.example.getcurrentruntimevalue;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MainActivity extends Activity {
private static final String SELECT_RUNTIME_PROPERTY = "persist.sys.dalvik.vm.lib";
private static final String LIB_DALVIK = "libdvm.so";
private static final String LIB_ART = "libart.so";
private static final String LIB_ART_D = "libartd.so";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView tv = (TextView)findViewById(R.id.current_runtime_value);
tv.setText(getCurrentRuntimeValue());
}
private CharSequence getCurrentRuntimeValue() {
try {
Class<?> systemProperties = Class.forName("android.os.SystemProperties");
try {
Method get = systemProperties.getMethod("get",
String.class, String.class);
if (get == null) {
return "WTF?!";
}
try {
final String value = (String)get.invoke(
systemProperties, SELECT_RUNTIME_PROPERTY,
/* Assuming default is */"Dalvik");
if (LIB_DALVIK.equals(value)) {
return "Dalvik";
} else if (LIB_ART.equals(value)) {
return "ART";
} else if (LIB_ART_D.equals(value)) {
return "ART debug build";
}
return value;
} catch (IllegalAccessException e) {
return "IllegalAccessException";
} catch (IllegalArgumentException e) {
return "IllegalArgumentException";
} catch (InvocationTargetException e) {
return "InvocationTargetException";
}
} catch (NoSuchMethodException e) {
return "SystemProperties.get(String key, String def) method is not found";
}
} catch (ClassNotFoundException e) {
return "SystemProperties class is not found";
}
}
}
Hope this helps.
For anyone needing a JNI version:
#include <sys/system_properties.h>
static bool isArtEnabled() {
char buf[PROP_VALUE_MAX] = {};
__system_property_get("persist.sys.dalvik.vm.lib.2", buf);
// This allows libartd.so to be detected as well.
return strncmp("libart", buf, 6) == 0;
}
Or if you want to follow a code path closer to what shoe rat posted,
static bool isArtEnabled(JNIEnv *env)
{
// Per https://developer.android.com/guide/practices/verifying-apps-art.html
// if the result of System.getProperty("java.vm.version") starts with 2,
// ART is enabled.
jclass systemClass = env->FindClass("java/lang/System");
if (systemClass == NULL) {
LOGD("Could not find java.lang.System.");
return false;
}
jmethodID getProperty = env->GetStaticMethodID(systemClass,
"getProperty", "(Ljava/lang/String;)Ljava/lang/String;");
if (getProperty == NULL) {
LOGD("Could not find java.lang.System.getProperty(String).");
return false;
}
jstring propertyName = env->NewStringUTF("java.vm.version");
jstring jversion = (jstring)env->CallStaticObjectMethod(
systemClass, getProperty, propertyName);
if (jversion == NULL) {
LOGD("java.lang.System.getProperty('java.vm.version') did not return a value.");
return false;
}
const char *version = env->GetStringUTFChars(jversion, JNI_FALSE);
// Lets flip that check around to better bullet proof us.
// Consider any version which starts with "1." to be Dalvik,
// and all others to be ART.
bool isArtEnabled = !(strlen(version) < 2 ||
strncmp("1.", version, 2) == 0);
LOGD("Is ART enabled? %d (%s)", isArtEnabled, version);
env->ReleaseStringUTFChars(jversion, version);
return isArtEnabled;
}
The Android docs actually give the following suggestion:
You can verify which runtime is in use by calling System.getProperty("java.vm.version"). If ART is in use, the property's value is "2.0.0" or higher.
This seems accurate on my Nexus 4 w/ ART enabled (running Android 4.4.4). Nexus 5 on Dalvik returned 1.6.0.
A simple solution :
String vm = System.getProperty("java.vm.name") + " " + System.getProperty("java.vm.version");
On my Android 8.0 (API 26) phone, it returns Dalvik 2.1.0 .
I think you should be able to use System.getProperty with java.vm.name as the key.
In the JavaDoc its value is Dalvik, which let's hope it is Art or ART when using that runtime. It's worth a try...
final String vm = VMRuntime.getRuntime().vmLibrary();
and then compare vm with "libdvm.so" or "libart.so" to check if it is Dalvik or ART.
Reference: https://gitorious.org/cyandreamproject/android_frameworks_base/commit/4c3f1e9e30948113b47068152027676172743eb1

Categories

Resources