Flutter Engine
The Flutter Engine
scoped_java_ref.h
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef FLUTTER_FML_PLATFORM_ANDROID_SCOPED_JAVA_REF_H_
6#define FLUTTER_FML_PLATFORM_ANDROID_SCOPED_JAVA_REF_H_
7
8#include <jni.h>
9
10#include <cstddef>
11
12#include "flutter/fml/macros.h"
13
14namespace fml {
15namespace jni {
16
17// Creates a new local reference frame, in which at least a given number of
18// local references can be created. Note that local references already created
19// in previous local frames are still valid in the current local frame.
21 public:
22 explicit ScopedJavaLocalFrame(JNIEnv* env);
23 ScopedJavaLocalFrame(JNIEnv* env, int capacity);
25
26 private:
27 // This class is only good for use on the thread it was created on so
28 // it's safe to cache the non-threadsafe JNIEnv* inside this object.
29 JNIEnv* env_;
30
31 FML_DISALLOW_COPY_AND_ASSIGN(ScopedJavaLocalFrame);
32};
33
34// Forward declare the generic java reference template class.
35template <typename T>
36class JavaRef;
37
38// Template specialization of JavaRef, which acts as the base class for all
39// other JavaRef<> template types. This allows you to e.g. pass
40// ScopedJavaLocalRef<jstring> into a function taking const JavaRef<jobject>&
41template <>
42class JavaRef<jobject> {
43 public:
44 jobject obj() const { return obj_; }
45
46 bool is_null() const { return obj_ == NULL; }
47
48 protected:
49 // Initializes a NULL reference.
50 JavaRef();
51
52 // Takes ownership of the |obj| reference passed; requires it to be a local
53 // reference type.
54 JavaRef(JNIEnv* env, jobject obj);
55
57
58 // The following are implementation detail convenience methods, for
59 // use by the sub-classes.
60 JNIEnv* SetNewLocalRef(JNIEnv* env, jobject obj);
61 void SetNewGlobalRef(JNIEnv* env, jobject obj);
62 void ResetLocalRef(JNIEnv* env);
63 void ResetGlobalRef();
64 jobject ReleaseInternal();
65
66 private:
67 jobject obj_;
68
69 FML_DISALLOW_COPY_AND_ASSIGN(JavaRef);
70};
71
72// Generic base class for ScopedJavaLocalRef and ScopedJavaGlobalRef. Useful
73// for allowing functions to accept a reference without having to mandate
74// whether it is a local or global type.
75template <typename T>
76class JavaRef : public JavaRef<jobject> {
77 public:
78 T obj() const { return static_cast<T>(JavaRef<jobject>::obj()); }
79
80 protected:
83
84 JavaRef(JNIEnv* env, T obj) : JavaRef<jobject>(env, obj) {}
85
86 private:
87 FML_DISALLOW_COPY_AND_ASSIGN(JavaRef);
88};
89
90// Holds a local reference to a Java object. The local reference is scoped
91// to the lifetime of this object.
92// Instances of this class may hold onto any JNIEnv passed into it until
93// destroyed. Therefore, since a JNIEnv is only suitable for use on a single
94// thread, objects of this class must be created, used, and destroyed, on a
95// single thread.
96// Therefore, this class should only be used as a stack-based object and from a
97// single thread. If you wish to have the reference outlive the current
98// callstack (e.g. as a class member) or you wish to pass it across threads,
99// use a ScopedJavaGlobalRef instead.
100template <typename T>
101class ScopedJavaLocalRef : public JavaRef<T> {
102 public:
103 ScopedJavaLocalRef() : env_(NULL) {}
104
105 // Non-explicit copy constructor, to allow ScopedJavaLocalRef to be returned
106 // by value as this is the normal usage pattern.
107 ScopedJavaLocalRef(const ScopedJavaLocalRef<T>& other) : env_(other.env_) {
108 this->SetNewLocalRef(env_, other.obj());
109 }
110
111 template <typename U>
112 explicit ScopedJavaLocalRef(const U& other) : env_(NULL) {
113 this->Reset(other);
114 }
115
116 // Assumes that |obj| is a local reference to a Java object and takes
117 // ownership of this local reference.
118 ScopedJavaLocalRef(JNIEnv* env, T obj) : JavaRef<T>(env, obj), env_(env) {}
119
121
122 // Overloaded assignment operator defined for consistency with the implicit
123 // copy constructor.
124 void operator=(const ScopedJavaLocalRef<T>& other) { this->Reset(other); }
125
126 void Reset() { this->ResetLocalRef(env_); }
127
128 template <typename U>
129 void Reset(const ScopedJavaLocalRef<U>& other) {
130 // We can copy over env_ here as |other| instance must be from the same
131 // thread as |this| local ref. (See class comment for multi-threading
132 // limitations, and alternatives).
133 this->Reset(other.env_, other.obj());
134 }
135
136 template <typename U>
137 void Reset(const U& other) {
138 // If |env_| was not yet set (is still NULL) it will be attached to the
139 // current thread in SetNewLocalRef().
140 this->Reset(env_, other.obj());
141 }
142
143 template <typename U>
144 void Reset(JNIEnv* env, U obj) {
145 env_ = this->SetNewLocalRef(env, obj);
146 }
147
148 // Releases the local reference to the caller. The caller *must* delete the
149 // local reference when it is done with it.
150 T Release() { return static_cast<T>(this->ReleaseInternal()); }
151
152 private:
153 // This class is only good for use on the thread it was created on so
154 // it's safe to cache the non-threadsafe JNIEnv* inside this object.
155 JNIEnv* env_;
156};
157
158// Holds a global reference to a Java object. The global reference is scoped
159// to the lifetime of this object. This class does not hold onto any JNIEnv*
160// passed to it, hence it is safe to use across threads (within the constraints
161// imposed by the underlying Java object that it references).
162template <typename T>
163class ScopedJavaGlobalRef : public JavaRef<T> {
164 public:
166
167 // NOLINTNEXTLINE(google-explicit-constructor)
169 this->Reset(other);
170 }
171
172 ScopedJavaGlobalRef(JNIEnv* env, T obj) { this->Reset(env, obj); }
173
174 template <typename U>
175 explicit ScopedJavaGlobalRef(const U& other) {
176 this->Reset(other);
177 }
178
180
181 void Reset() { this->ResetGlobalRef(); }
182
183 template <typename U>
184 void Reset(const U& other) {
185 this->Reset(NULL, other.obj());
186 }
187
188 template <typename U>
189 void Reset(JNIEnv* env, U obj) {
190 this->SetNewGlobalRef(env, obj);
191 }
192
193 // Releases the global reference to the caller. The caller *must* delete the
194 // global reference when it is done with it.
195 T Release() { return static_cast<T>(this->ReleaseInternal()); }
196};
197
198} // namespace jni
199} // namespace fml
200
201#endif // FLUTTER_FML_PLATFORM_ANDROID_SCOPED_JAVA_REF_H_
JavaRef(JNIEnv *env, T obj)
void Reset(const U &other)
ScopedJavaGlobalRef(const ScopedJavaGlobalRef< T > &other)
ScopedJavaGlobalRef(JNIEnv *env, T obj)
void Reset(JNIEnv *env, U obj)
ScopedJavaLocalRef(const U &other)
void Reset(JNIEnv *env, U obj)
void operator=(const ScopedJavaLocalRef< T > &other)
ScopedJavaLocalRef(JNIEnv *env, T obj)
void Reset(const ScopedJavaLocalRef< U > &other)
void Reset(const U &other)
ScopedJavaLocalRef(const ScopedJavaLocalRef< T > &other)
Definition: __init__.py:1
Definition: ascii_trie.cc:9
#define T
Definition: precompiler.cc:65