简体   繁体   English

Android,如何在 AsyncTask 中启动领域?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM