bind/java: Do not get ApplicationContext via reflection, ask for it when needed.

Previously any library created using gobind used reflection to get the ApplicationContext. The methods used are disallowed in Android 9 causing any library to crash.  However the ApplictionContext is not required and only needed when using RunOnJvm. This change adds an method to set the ApplicationContext when needed, but will not get it by default by using reflection.

Fixes #31364

Change-Id: I83ce69f3b4b59d2cc4a275928f0439e5e4651ba8
GitHub-Last-Rev: b563af1d7f
GitHub-Pull-Request: golang/mobile#31
Reviewed-on: https://go-review.googlesource.com/c/mobile/+/175103
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
This commit is contained in:
Tim Cooijmans 2019-07-11 09:26:40 +00:00 коммит произвёл Hyang-Ah Hana Kim
Родитель 6fa95d984e
Коммит e47acb2ca7
3 изменённых файлов: 9 добавлений и 51 удалений

Просмотреть файл

@ -1,37 +0,0 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package go;
import android.app.Application;
import android.content.Context;
import java.util.logging.Logger;
// LoadJNI is a shim class used by 'gomobile bind' to auto-load the
// compiled go library and pass the android application context to
// Go side.
//
// TODO(hyangah): should this be in cmd/gomobile directory?
public class LoadJNI {
private static Logger log = Logger.getLogger("GoLoadJNI");
public static final Object ctx;
static {
System.loadLibrary("gojni");
Object androidCtx = null;
try {
// TODO(hyangah): check proguard rule.
Application appl = (Application)Class.forName("android.app.AppGlobals").getMethod("getInitialApplication").invoke(null);
androidCtx = appl.getApplicationContext();
} catch (Exception e) {
log.warning("Global context not found: " + e);
} finally {
ctx = androidCtx;
}
}
}

Просмотреть файл

@ -4,6 +4,8 @@
package go;
import android.content.Context;
import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
@ -32,23 +34,16 @@ public class Seq {
private static final GoRefQueue goRefQueue = new GoRefQueue();
static {
// Look for the shim class auto-generated by gomobile bind.
// Its only purpose is to call System.loadLibrary.
try {
Class loadJNI = Class.forName("go.LoadJNI");
setContext(loadJNI.getDeclaredField("ctx").get(null));
} catch (ClassNotFoundException e) {
// Ignore, assume the user will load JNI for it.
log.warning("LoadJNI class not found");
} catch (NoSuchFieldException e) {
log.severe("LoadJNI class missing field: " + e);
} catch (IllegalAccessException e) {
log.severe("LoadJNI class bad field: " + e);
}
System.loadLibrary("gojni");
init();
Universe.touch();
}
// setContext sets the context in the go-library to be used in RunOnJvm.
public static void setContext(Context context) {
setContext((java.lang.Object)context);
}
private static native void init();
// Empty method to run class initializer

Просмотреть файл

@ -86,7 +86,7 @@ func genPkg(lang string, p *types.Package, astFiles []*ast.File, allPkg []*types
return
}
repo := filepath.Clean(filepath.Join(p.Dir, "..")) // golang.org/x/mobile directory.
for _, javaFile := range []string{"Seq.java", "LoadJNI.java"} {
for _, javaFile := range []string{"Seq.java"} {
src := filepath.Join(repo, "bind/java/"+javaFile)
in, err := os.Open(src)
if err != nil {