[英]Android, how to initiate realm in AsyncTask?
I have an asyncTask in my application as below.我的应用程序中有一个 asyncTask,如下所示。 I have to fetch data from realm(which is successfully stored in another activity) into this AsyncTask.
我必须从领域(已成功存储在另一个活动中)获取数据到这个 AsyncTask 中。 Below is my AsyncTask code:
下面是我的 AsyncTask 代码:
public class MakeAsyncRequest extends AsyncTask<Object, String, MakeAsyncRequest.ResponseDataType>{
public Context asyncContext;
private MakeAsyncRequest(Context context){
asyncContext = context;
}
private static final OkHttpClient client = new OkHttpClient();
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
private MakeRequest.ResponseHandler handler;
private String method;
private User user;
private Realm realm;
class ResponseDataType
{
InputStream inputStream;
String string;
String cookie;
}
MakeAsyncRequest(MakeRequest.ResponseHandler responseHandler, String type)
{
method = type;
handler = responseHandler;
}
@Override
protected ResponseDataType doInBackground(Object... params) {
try {
Requests requests = new Requests((Context) params[0]);
String url = params[1].toString();
String bodyJson = null;
if(method.equals("PUT") || method.equals("POST")) {
bodyJson = params[2].toString();
}
final Request.Builder builder;
Response response;
RequestBody body;
switch (method) {
case "GET": builder = new Request.Builder().url(url);
break;
case "DOWNLOAD": builder = new Request.Builder().url(url);
break;
case "POST": body = RequestBody.create(JSON, bodyJson);
builder = new Request.Builder()
.url(url)
.post(body)
.addHeader("Cookie", "key=value");
break;
case "PUT": body = RequestBody.create(JSON, bodyJson);
builder = new Request.Builder()
.url(url)
.put(body);
break;
default: builder = new Request.Builder().url(url);
}
builder.addHeader("Accept", "application/json");
realm = RealmController.initialize(this).getRealm();
final RealmResults<User> users = realm.where(User.class).findAllAsync();
user = users.first();
if(user.getCookie() !== null && !user.getCookie().isEmpty()){
builder.addHeader("cookie", "user.getCookie()");
}
response = client.newCall(builder.build()).execute();
ResponseDataType responseDataType = new ResponseDataType();
if(method.equals("DOWNLOAD")) { responseDataType.inputStream = response.body().byteStream(); }
else {
responseDataType.string = response.body().string();
responseDataType.cookie = response.headers().get("set-cookie");
CookieManager cManager = new CookieManager(null, CookiePolicy.ACCEPT_ALL);
cManager.getCookieStore().getCookies();
}
return responseDataType;
} catch (IOException e) {
return null;
}
}
@Override
protected void onPostExecute(ResponseDataType response) {
try {
if (method.equals("DOWNLOAD")) {
handler.onFinishCallback(response.inputStream);
}else {
handler.onFinishCallback(response.string, response.cookie);
CookieManager cManager = new CookieManager(null, CookiePolicy.ACCEPT_ALL);
cManager.getCookieStore().getCookies();
}
}catch (Exception e){
Log.d("hExceptionError", e.toString());
handler.onFinishCallback("{\n" +
" \"error\": \"error\"\n" +
"}","");
}
}
I am received the access error - "Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created."我收到访问错误 - “来自错误线程的领域访问。领域对象只能在它们创建的线程上访问。” whenever the control tries to execute the Realm results or to get the first object from Realm.
每当控件尝试执行 Realm 结果或从 Realm 获取第一个对象时。
Below is my RealmController which i created to control the realm instance:下面是我为控制领域实例而创建的 RealmController:
public class RealmController {`public static RealmController initialize(Activity activity) {
if (instance == null) {
instance = new RealmController(activity.getApplication());
}
return instance;
}
public static RealmController initialize(MakeAsyncRequest activity) {
if (instance == null) {
instance = new RealmController(activity.);
}
return instance;
}
}`
I have my user model(Realm object) with setters and getters.我有带有 setter 和 getter 的用户模型(领域对象)。
The point is - you cannot create and access Realm on different threads, ie create Realm instance in Activity and use it in .doInBackground() method.关键是 - 您不能在不同的线程上创建和访问 Realm,即在 Activity 中创建 Realm 实例并在 .doInBackground() 方法中使用它。 Create and release Realm immediately before and after transaction.
在事务之前和之后立即创建和释放 Realm。 There may be another issue - don't register quer observer on background thread in AsyncTask - it doesn't have Looper initialized - use main thread or HandlerThread.
可能还有另一个问题 - 不要在 AsyncTask 的后台线程上注册查询观察者 - 它没有初始化 Looper - 使用主线程或 HandlerThread。 Release realm after it is no longer needed (you didn't in your code), because Realm has limited number of instances.
在不再需要领域后释放领域(您的代码中没有),因为领域的实例数量有限。
将 Realm.getDefaultInstance() 放入 doInBackground
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.