【问题标题】:Set class variable from interface implemented function and AsyncTask从接口实现的函数和 AsyncTask 设置类变量
【发布时间】:2015-02-15 00:19:15
【问题描述】:

如果您认为问题描述不正确,请更正标题。

我想通过一个实现的接口设置一个类变量,然后返回给另一个调用这个函数的类。

这里是代码。我使用 AsyncTask 和 Interface 的直接组合从 onPostExecute 返回一个对象:

public boolean isUserLoggedIn() throws ExecutionException, InterruptedException {
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("tag", is_user_logged_in_tag));
    jsonParser = new DbHandler(new DBinterface() {
        @Override
        public void onRemoteCallComplete(JSONObject jsonFromNet) throws JSONException, ExecutionException, InterruptedException {
            if (Integer.parseInt(jsonFromNet.getString("num_rows")) > 0) {
                isLoggedIn = true;
            } else {
                isLoggedIn = false;
            }
        }
    }, params).execute();
    System.out.println("DEBUG[10] " + isLoggedIn);
    return isLoggedIn;
}

isLoggedIn 声明为:

私有布尔 isLoggedIn = false;

所以我使用另一个类的这个函数来检查用户是否登录:

public class DashboardActivity extends Activity { 

        userFunctions = new UserFunctions(this);


            userFunctions.isUserLoggedIn();

        try {
            if(userFunctions.isUserLoggedIn()){
             //It nevers enters here as isUserLoggedIn always return the initial FALSE value.                              
                setContentView(R.layout.dashboard);
                btnLogout = (Button) findViewById(R.id.btnLogout);
.....
.....
}

我的问题是 isLoggedIn 仍然 always false,因为我使用 AsyncTask 查询数据库以检查用户是否已登录。即使使用 get() 方法它也不起作用。

AsyncTask 的 onPostExecute:

@Override
protected void onPostExecute(JSONObject jsonObject) {
    super.onPostExecute(jsonObject);
    try {
        System.out.println(jsonObject.toString(1));
        intf.onRemoteCallComplete(jsonObject);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

解决方案:

public class DashboardActivity extends Activity implements MyCallback {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dummy_layout);
        // Check login status in database

        userFunctions = new UserFunctions(this);

        try {
            userFunctions.isUserLoggedIn(this);
...
...
}

@Override
public void onRemoteCallComplete(JSONObject jsonFromNet) throws JSONException, ExecutionException, InterruptedException {
    checkUserState(jsonFromNet.getString("num_rows"));
}


private void checkUserState(String num_rows) {
    if (Integer.parseInt(num_rows) > 0) {
        pDialog.dismiss();
        setContentView(R.layout.dashboard);
        btnLogout = (Button) findViewById(R.id.btnLogout);
        btnLogout.setOnClickListener(new View.OnClickListener() {
            public void onClick(View arg0) {
                // TODO Auto-generated method stub
                try {
                    userFunctions.logoutUser(new MyCallback() {
                        @Override
                        public void onRemoteCallComplete(JSONObject jsonFromNet) throws JSONException, ExecutionException, InterruptedException {

                        }
                    });
                } catch (ExecutionException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Intent login = new Intent(getApplicationContext(), MainActivity.class);
                login.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(login);
                // Closing dashboard screen
                finish();
            }
        });

    } else {
        // user is not logged in show login screen
        Intent login = new Intent(getApplicationContext(), MainActivity.class);
        login.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(login);
        // Closing dashboard screen
        finish();
    }
}

这是经过简化的 isUserLoggedIn:

public void isUserLoggedIn(MyCallback callback) throws ExecutionException, InterruptedException {
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("tag", is_user_logged_in_tag));
    jsonParser = (DbHandler) new DbHandler(activity, callback, params).execute();
}

【问题讨论】:

  • 因为 AsyncTask 还没有完成?
  • 是的,我知道。这就是我寻求帮助的原因...

标签: java android interface android-asynctask


【解决方案1】:

问题是isUserLoggedIn() 方法立即返回当前状态,但它在此过程中启动了DbHandler。所以isUserLoggedIn() 的调用者并没有等待结果。重新编写Activity 代码以检查登录状态(因此将isUserLoggedIn() 修改为checkUserLoginStatus()。在AsyncTask.onPostExecute() 中,您需要“通知”Activity 最新状态。这里要小心,因为您需要确保您的 AsyncTask 与您的 Activity 的生命周期仔细协调。它不知道生命周期,因此如果您尝试直接操作 UI 组件,则可能会得到 IllegalStateException,如果Activity 未处于运行状态。

【讨论】:

  • 我会尝试根据您的回答重新编写我的代码。问题是我不想更改 asynctask,因为它用于多个任务。
  • 如果能给出一些代码示例就好了
  • @ManosKontakis 试试这篇文章,看看它是否有助于理解 AsyncTask 并使用它:po.st/Cei3m2
  • 谢谢你,我会的!我是否必须将活动对象传递给 AsyncTask 以通知活动有关用户的状态?
  • 有几种不同的处理方式,例如直接使用Activity,使用WeakReference 或使用回调接口。如果您允许AsyncTask 具有对Activity 的强引用,那么您可能会导致内存泄漏。但是,如果你仔细协调 w/onPause() 那就可以了。
【解决方案2】:

您可以将变量存储在存储的首选项中。

在异步任务的后期执行中,如果登录是肯定的,则存储结果如下:

 SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPref.edit();
    editor.putInt("LOGGEDIN", "1");
    editor.commit();

然后像这样读取你的变量:

SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);

    String loggedin = sharedPref.getString("LOGGEDIN"), "0");

在私有方法中设置上述读取以检查返回布尔值 isLoggedIn 的 logIn。

【讨论】:

    猜你喜欢
    • 2016-07-03
    • 1970-01-01
    • 1970-01-01
    • 2019-12-17
    • 2019-01-01
    • 1970-01-01
    • 2017-12-24
    • 2014-02-25
    • 2022-08-05
    相关资源
    最近更新 更多