簡體   English   中英

Android,如何在 AsyncTask 中啟動領域?

[英]Android, how to initiate realm in AsyncTask?

我的應用程序中有一個 asyncTask,如下所示。 我必須從領域(已成功存儲在另一個活動中)獲取數據到這個 AsyncTask 中。 下面是我的 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" +
                "}","");
    }
}

我收到訪問錯誤 - “來自錯誤線程的領域訪問。領域對象只能在它們創建的線程上訪問。” 每當控件嘗試執行 Realm 結果或從 Realm 獲取第一個對象時。

下面是我為控制領域實例而創建的 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;
}
}`

我有帶有 setter 和 getter 的用戶模型(領域對象)。

關鍵是 - 您不能在不同的線程上創建和訪問 Realm,即在 Activity 中創建 Realm 實例並在 .doInBackground() 方法中使用它。 在事務之前和之后立即創建和釋放 Realm。 可能還有另一個問題 - 不要在 AsyncTask 的后台線程上注冊查詢觀察者 - 它沒有初始化 Looper - 使用主線程或 HandlerThread。 在不再需要領域后釋放領域(您的代碼中沒有),因為領域的實例數量有限。

將 Realm.getDefaultInstance() 放入 doInBackground

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM