【问题标题】:Intent not working with Async task in Android?Intent 不适用于 Android 中的异步任务?
【发布时间】:2014-03-06 05:28:11
【问题描述】:

我的 Aysnc 任务未使用 Intent 显示下一个活动。如果我想使用异步任务切换到下一个活动,也应该在哪里调用 Intent。下面是我的代码。

btn_login.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {
            // TODO Auto-generated method stub

                new Login_LC(getApplicationContext.this).execute();
                countriesList();

            }else {
            }
        }
    });


 private class Login_LC extends AsyncTask<String, Void, String> {
    private ProgressDialog dialog;
    String status = "";
    Context ctx;
    //  String auth_token;
    public Login_LC(Context context) {
        dialog = new ProgressDialog(context);
    }

    @Override
    protected void onPreExecute() {
        this.dialog.setMessage("Please wait...");
        this.dialog.setCancelable(false);
        this.dialog.setCanceledOnTouchOutside(false);
        this.dialog.show();
    }

    @Override
    protected String doInBackground(String... urls) {
        String response = "";

        response = new SOAPService().authUser(urls[0], urls[1]);
        System.out.println("RESPONSE= " + response);

        status = new Auth_token().getStatus(response);
        System.out.println("STATUS= " + status);
        return status;
    }

    protected void onPostExecute(String s) {

        System.out.println("S= " + s);

                try{
                    JSONObject jsonObj = MainActivity.jsonObj.getJSONObject("data");
                    if(jsonObj!=null){
                        String req_Token = jsonObj.getString("request_token");
                        //      req_token = req_Token;
                        new GetSubAccount(someclass.this, req_Token).execute();    //Async task Below called here
                    }
                }
                catch(Exception e){
                    System.out.print("----" +e);
                }
                Toast.makeText(someclass.this, "Login successfull", Toast.LENGTH_LONG).show();

                try{

                Intent loginIntent = new Intent(ctx, Dialpad.class);
                ctx.startActivity(loginIntent);
                }
                catch(Exception e){
                    System.out.print("-----"+e);
                }

            }else if(s.equals("failed")){
                Toast.makeText(someclass.this,"Wrong username/password!",Toast.LENGTH_SHORT).show();
            }

            else {

                Toast.makeText(someclass.this, "Login failed!",
                        Toast.LENGTH_LONG).show();
            }

        }else{
            if(dialog.isShowing()){
                dialog.dismiss();
            }

            Toast.makeText(someclass.this,"No response from server!Please try again.",Toast.LENGTH_LONG).show();
        }
    }
}

子帐户:

private class GetSubAccount extends AsyncTask<String, Void, String> {

    JSONObject jsonObj;
    String req_Token;
    Vector numberList;
    Context ctx;

    private ProgressDialog dialog;

    public GetSubAccount(Context context, String req_Token) {
        // TODO Auto-generated constructor stub
        dialog = new ProgressDialog(context);
        this.req_Token = req_Token;
    }

    @Override
    protected void onPreExecute() {
        this.dialog.setMessage("Please wait...");
        this.dialog.setCancelable(false);
        this.dialog.setCanceledOnTouchOutside(false);
        this.dialog.show();
    }

    @Override
    protected String doInBackground(String... params) {
        // TODO Auto-generated method stub

        String response  = null;

        try{
            response = new SOAPService().subAccount(req_Token);
            jsonObj = new JSONObject(response);

        }catch(Exception e){
            System.out.print("Exception-----"+e);
        }
        return response;
    }

    @Override
    protected void onPostExecute(String s) {
        if(s!=null){
            if (dialog.isShowing()) {
                dialog.dismiss();
            }
            try{
                if (s.equals("success")) {
                    try{    
                        numberList = new Vector();
                                            myNumbers = new Vector();   //  this Vector used in next Activity   
                        JSONObject jObj1 = jsonObj.getJSONObject("data");
                        JSONArray jArr = jObj1.getJSONArray("PhoneNumber");
                        for(int i=0;i<=jArr.length();i++){
                            numberList.add(jArr.getString(i));
                            System.out.print("number-----  "+numberList);

                            JSONObject jObj2 = jArr.getJSONObject(i);
                            myNumbers.add(jObj2.getString("number"));       
                        }                       
                    }
                    catch(Exception e){
                        System.out.print("Device Exception---" +e);
                    }
                }
            }
            catch(Exception e){
                System.out.print("------"+e);
            }
        }else{
        }
    }
}

// 意图不工作?在哪里调用 Intent?请帮忙。谢谢。 :)

【问题讨论】:

  • 你有什么错误吗?
  • @SiddharthVyas 空指针异常仅在我调试时...
  • 请发布您的 logcat 错误。
  • @Shandroid 你可以使用单个异步任务。如果成功启动新活动,则基于该请求最终解析第一个响应。我认为您的工作不需要 2 个 Asynctask。
  • 你没有初始化你的 Context 对象 ctx...初始化它

标签: android android-intent android-asynctask


【解决方案1】:

onPostExecute 中有以下内容,这很好。但是意图需要一个有效的上下文作为参数。你说你得到NullPointerException。查看代码上下文ctx未初始化

Intent loginIntent = new Intent(ctx, Dialpad.class);
ctx.startActivity(loginIntent);

你还没有初始化上下文

Context ctx;
//  String auth_token;
public Login_LC(Context context) {
    dialog = new ProgressDialog(context);
    ctx =context;  
}

但是如果 AsyncTask 是一个内部类你不需要初始化你可以直接使用startActivity

你也有

new Login_LC(getApplicationContext.this).execute();

使用

new Login_LC(ActivityName.this).execute();

同样

 Context ctx;

    private ProgressDialog dialog;

    public GetSubAccount(Context context, String req_Token) {
        // TODO Auto-generated constructor stub
        dialog = new ProgressDialog(context);
        this.req_Token = req_Token;
        ctx = context;
    }

也可以通过commonsware @查看答案

When to call activity context OR application context?

我想当登录按钮按下它调用 login_LC 异步任务,然后在 它调用子帐户异步任务,然后显示下一个活动。也在 下一个活动我正在使用子帐户发布结果。

你有

new GetSubAccount(someclass.this, req_Token).execute();

在第一个 AsyncTask 的 onPostExecute 中很好。我猜someclass.this 是 Activity 上下文。

删除第一个 Asynctask 中的 startActivity 代码并将其移至第二个 Asynctask 的 onPostExecue

   @Override
    protected void onPostExecute(String s) {
        if(s!=null){
              dialog.dismiss();
              try{
                if (s.equals("success")) {

                        numberList = new Vector();
                        myNumbers = new Vector();   //  this Vector used in next Activity   
                        JSONObject jObj1 = jsonObj.getJSONObject("data");
                        JSONArray jArr = jObj1.getJSONArray("PhoneNumber");
                        for(int i=0;i<=jArr.length();i++){
                            numberList.add(jArr.getString(i));
                            System.out.print("number-----  "+numberList);
                            JSONObject jObj2 = jArr.getJSONObject(i);
                            myNumbers.add(jObj2.getString("number"));       
                        } 
                        Intent loginIntent = new Intent(ctx, Dialpad.class);
                       ctx.startActivity(loginIntent);
                }else{

                }                      

            }
            catch(Exception e){
                System.out.print("------"+e);
            }
        }
  }

【讨论】:

  • Man Q 是在哪里打电话给startActivity(intent),你的回答没有提到。
  • @SuperUser 他在onPostExecute 中有这个Intent loginIntent = new Intent(ctx, Dialpad.class); ctx.startActivity(loginIntent); 很好。正如正确指出的那样,它需要一个上下文。在他的评论中操作点@NPE
  • 我在下一个活动中得到“数字”数组,例如 String[] = new String[someclass.myNumbers.size()]; ,它在那里给出错误?
【解决方案2】:

尝试像这样开始新活动:

    @Override
    protected void onPostExecute(Void result) 
    {
        super.onPostExecute(result);
        Intent intent = new Intent(MyAsyncTaskActivity.this, NextActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
        getApplicationContext().startActivity(intent);
    }

【讨论】:

    【解决方案3】:

    你没有初始化你的Context对象ctx...初始化它如下。

    Login_LC 类...

    Context ctx;
    public Login_LC(Context context) {
    
        this.ctx = context;
        dialog = new ProgressDialog(context);
    }
    

    GetSubAccount 类...

    Context ctx;
    public GetSubAccount(Context context, String req_Token) {
    
        this.ctx = context;
    
        // TODO Auto-generated constructor stub
        dialog = new ProgressDialog(context);
        this.req_Token = req_Token;
    }
    

    并在btn_loginOnCLickListener 中传递您的Activity Context,如下所示...

    new Login_LC(YourActivity).execute();
    

    更新:

    如果你想从Login_LC 开始你的GetSubAccount asynctask,然后传递你从Login_LC 构造函数获得的Context,如下所示...

    new GetSubAccount(ctx).execute();
    

    更新您的onPostExecute()Login_LC 类如下...

    @Override
    protected void onPostExecute(String s) {
    
        System.out.println("S= " + s);
    
                try{
                    JSONObject jsonObj = ctx.jsonObj.getJSONObject("data");
                    if(jsonObj!=null){
                        String req_Token = jsonObj.getString("request_token");
                        //      req_token = req_Token;
                        new GetSubAccount(ctx, req_Token).execute();    //Async task Below called here
                    }
                }
                catch(Exception e){
                    System.out.print("----" +e);
                }
                Toast.makeText(ctx, "Login successfull", Toast.LENGTH_LONG).show();
    
                try{
    
                Intent loginIntent = new Intent(ctx, Dialpad.class);
                ctx.startActivity(loginIntent);
                }
                catch(Exception e){
                    System.out.print("-----"+e);
                }
    
            }else if(s.equals("failed")){
                Toast.makeText(ctx,"Wrong username/password!",Toast.LENGTH_SHORT).show();
            }
    
            else {
    
                Toast.makeText(ctx, "Login failed!", Toast.LENGTH_LONG).show();
            }
    
        }else{
            if(dialog.isShowing()){
                dialog.dismiss();
            }
    
            Toast.makeText(ctx,"No response from server!Please try again.",Toast.LENGTH_LONG).show();
        }
    }
    

    如下更新GetSubAccount 类的onPostExecute() 方法...

    @Override
    protected void onPostExecute(String s) {
        if(s!=null){
            if (dialog.isShowing()) {
                dialog.dismiss();
            }
            try{
                if (s.equals("success")) {
                    try{    
                        numberList = new Vector();
                                            myNumbers = new Vector();   //  this Vector used in next Activity   
                        JSONObject jObj1 = jsonObj.getJSONObject("data");
                        JSONArray jArr = jObj1.getJSONArray("PhoneNumber");
                        for(int i=0;i<=jArr.length();i++){
                            numberList.add(jArr.getString(i));
                            System.out.print("number-----  "+numberList);
    
                            JSONObject jObj2 = jArr.getJSONObject(i);
                            myNumbers.add(jObj2.getString("number"));       
                        }                       
                    }
                    catch(Exception e){
                        System.out.print("Device Exception---" +e);
                    }
                }
            }
            catch(Exception e){
                System.out.print("------"+e);
            }
    
            //start your activity here
            Intent loginIntent = new Intent(ctx, Dialpad.class);
            ctx.startActivity(loginIntent);
    
        }else{
        }
    }
    

    【讨论】:

    • Login_LC 异步任务在登录按钮按下时调用,GetSubAccount 异步任务在 Login_LC 中。这是混乱。现在在哪里调用 Intent 它也给出了空指针异常。
    • @Shandroid 你想什么时候开始活动?在某些条件或某些代码执行后?
    • 我想在登录按钮按下时调用 login_LC 异步任务,然后在其中调用子帐户异步任务,然后显示下一个活动。同样在下一个活动中,我正在使用子帐户发布结果。
    • @Shandroid...查看我更新的答案并发布NullPointerExceptionLogCat
    • @Shandroid 登录成功时您不调用其他异步任务吗?所以当登录成功时开始新的活动。如果不调用 asynctask 并在其他 asynctask 的 onPostexecute 中启动 activtiy
    【解决方案4】:

    由于您没有初始化上下文...替换 loginIntent onPostexecute

    Intent loginIntent = new Intent(ctx, Dialpad.class);
    ctx.startActivity(loginIntent);
    

    Intent loginIntent = new Intent(dialog.getContext(), Dialpad.class);
    dialog.getContext().startActivity(loginIntent);
    

    【讨论】:

      猜你喜欢
      • 2017-08-24
      • 2017-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-17
      • 1970-01-01
      • 2023-04-01
      相关资源
      最近更新 更多