Java Android异步任务和对象传递

Java Android异步任务和对象传递,java,android,android-asynctask,Java,Android,Android Asynctask,我需要一些关于登录过程中代码基本架构的帮助。我正在实现异步Http处理,以使ICS能够正常工作 此代码的目标是登录到我的应用程序 从UI提交登录表单(Login.java) 连接到我们的服务器并通过http get XML结果传递用户名/密码 将XML结果解析为数组。(ParseXML.java) 在UI中显示结果反馈 现在这一切都在我的程序中起作用了,但在尝试使用强制Asyc HTTP连接的ICS进行测试后,我很快意识到了我的问题,并使我怀疑我的整个设计 它目前的基本工作方式: Login

我需要一些关于登录过程中代码基本架构的帮助。我正在实现异步Http处理,以使ICS能够正常工作

此代码的目标是登录到我的应用程序

  • 从UI提交登录表单(Login.java)
  • 连接到我们的服务器并通过http get XML结果传递用户名/密码
  • 将XML结果解析为数组。(ParseXML.java)
  • 在UI中显示结果反馈
现在这一切都在我的程序中起作用了,但在尝试使用强制Asyc HTTP连接的ICS进行测试后,我很快意识到了我的问题,并使我怀疑我的整个设计

它目前的基本工作方式:

Login.java:

  class Login {
    ...
    ParseXML myXMLParser = new ParseXML();  
    myXMLParser.doLogin(username, password, Login.this);    

    public doFinished(result) {
      // update UI
    }
    ...
  }
  class ParseXML {
    // class variable to hold login object for async to access
    public Login loginObj;
    ...
    public void doLogin(String _username, String _password, Login _l) {
      loginObj = (Login) _l;
      ...

      // create loginUrl string to run through async
      ...
      new DownloadFilesTask().execute(loginUrl);
    }

    class DownloadFilesTask extends AsyncTask<a, b, c> {
      doInBackground() {
        // do stuff
        // download result of http call
        // parse XML
      }

      onPostExecute(result) {        
        // call the public class variable of login object i have and tell it to update the UI
        // pass back the result array.
        loginObj.doFinished(result);
      }
    }
  }
ParseXML.java:

  class Login {
    ...
    ParseXML myXMLParser = new ParseXML();  
    myXMLParser.doLogin(username, password, Login.this);    

    public doFinished(result) {
      // update UI
    }
    ...
  }
  class ParseXML {
    // class variable to hold login object for async to access
    public Login loginObj;
    ...
    public void doLogin(String _username, String _password, Login _l) {
      loginObj = (Login) _l;
      ...

      // create loginUrl string to run through async
      ...
      new DownloadFilesTask().execute(loginUrl);
    }

    class DownloadFilesTask extends AsyncTask<a, b, c> {
      doInBackground() {
        // do stuff
        // download result of http call
        // parse XML
      }

      onPostExecute(result) {        
        // call the public class variable of login object i have and tell it to update the UI
        // pass back the result array.
        loginObj.doFinished(result);
      }
    }
  }
classparsexml{
//类变量来保存异步访问的登录对象
公共登录loginObj;
...
public void doLogin(字符串\u用户名、字符串\u密码、登录名){
loginObj=(登录)\u l;
...
//创建loginUrl字符串以通过异步运行
...
新的下载文件任务().execute(loginUrl);
}
类DownloadFilesTask扩展了AsyncTask{
doInBackground(){
//做事
//下载http调用的结果
//解析XML
}
onPostExecute(结果){
//调用我拥有的login对象的公共类变量,并告诉它更新UI
//传回结果数组。
loginObj.doFinished(结果);
}
}
}
我最担心的是,这样做的设计很糟糕,我应该简单地将XML和http连接代码移动到Login.java文件中,使其全部包含在内(UI、http、XML解析、Asyc)

我特别关心的是从onPostExecute()调用Login.doFinished()。这对记忆力有害吗?我担心这会导致ParseXML对象避免垃圾收集,因为它现在将返回登录活动,一旦用户登录并保持ParseXML打开,该活动将继续运行

我来自PHP背景,因此我一直在尝试将所有XML解析和HTTP处理都保存在
ParseXML
模块中,以便我知道在哪里可以找到对此的更改

目前,
ParseXML
处理所有http工作,即,
getUsers
getChannels
addUser
delUser
doLogin
等。但是我是否应该尝试在相关屏幕/活动中移动所有代码来处理XML和http连接(异步),使它们是自包含的


我非常感谢您在这篇文章中提供的任何帮助。我假设您有一个LoginActivity,它创建一个ParseXML,然后有一个LoginObject(您能称之为“LoginCallback”?)将结果返回给显示结果的LoginActivity。这应该是可行的,这是一种经常使用的回调模式。回调通常定义为接口,而不是类


另一种方法是在LoginActivity中启动AsyncTask,在其doInBackground中调用ParseXML,并将结果直接返回到onPostExecute中的LoginActivity。

在这种情况下,我将使用接口

下载helper.java

public interface DownloadHelper 
{
   public void OnDownloadFinish(String Response);
   public void OnDownloadFailed(String Response); 
}
class Login {

    DownloadHelper helper=new DownloadHelper()
    {
      public void OnDownloadFinish(String Response)
       {
           // update UI

       } 

      public void OnDownloadFailed(String Response)
       {
           //Take Action
       }     
    };  


    new ParseXMLTask(this,helper).execute(username, password);
}
class ParseXMLTask extends AsyncTask<Object,Object,Object>
{
    DownloadHelper helper;
    public ParseXMLTask (Context context,DownloadHelper helper)
    {
       this.helper=helper;
    }   
    public void onPreExecute(){}

    public Object DoInBackground(Object object)
    {
       // do stuff
      // download result of http call
     // parse XML
     return parsed response
    }  

   public void onPostExceute(Object object)
    {

       helper.OnDownloadFinish((String)object);
       or
        helper.OnDownloadFailed((String)object);

    }
}
Login.java

public interface DownloadHelper 
{
   public void OnDownloadFinish(String Response);
   public void OnDownloadFailed(String Response); 
}
class Login {

    DownloadHelper helper=new DownloadHelper()
    {
      public void OnDownloadFinish(String Response)
       {
           // update UI

       } 

      public void OnDownloadFailed(String Response)
       {
           //Take Action
       }     
    };  


    new ParseXMLTask(this,helper).execute(username, password);
}
class ParseXMLTask extends AsyncTask<Object,Object,Object>
{
    DownloadHelper helper;
    public ParseXMLTask (Context context,DownloadHelper helper)
    {
       this.helper=helper;
    }   
    public void onPreExecute(){}

    public Object DoInBackground(Object object)
    {
       // do stuff
      // download result of http call
     // parse XML
     return parsed response
    }  

   public void onPostExceute(Object object)
    {

       helper.OnDownloadFinish((String)object);
       or
        helper.OnDownloadFailed((String)object);

    }
}
ParseXMLTask.java

public interface DownloadHelper 
{
   public void OnDownloadFinish(String Response);
   public void OnDownloadFailed(String Response); 
}
class Login {

    DownloadHelper helper=new DownloadHelper()
    {
      public void OnDownloadFinish(String Response)
       {
           // update UI

       } 

      public void OnDownloadFailed(String Response)
       {
           //Take Action
       }     
    };  


    new ParseXMLTask(this,helper).execute(username, password);
}
class ParseXMLTask extends AsyncTask<Object,Object,Object>
{
    DownloadHelper helper;
    public ParseXMLTask (Context context,DownloadHelper helper)
    {
       this.helper=helper;
    }   
    public void onPreExecute(){}

    public Object DoInBackground(Object object)
    {
       // do stuff
      // download result of http call
     // parse XML
     return parsed response
    }  

   public void onPostExceute(Object object)
    {

       helper.OnDownloadFinish((String)object);
       or
        helper.OnDownloadFailed((String)object);

    }
}
类ParseXMLTask扩展了AsyncTask { 下载助手; 公共ParseXMLTask(上下文,DownloadHelper) { this.helper=helper; } public void onPreExecute(){} 公共对象DoInBackground(对象) { //做事 //下载http调用的结果 //解析XML 返回解析的响应 } 公共无效OnPostExcute(对象) { OnDownloadFinish((字符串)对象); 或 helper.OnDownloadFailed((字符串)对象); } } 我应该简单地将XML和http连接代码移动到Login.java文件中,使其全部包含在内(UI、http、XML解析、Asyc)。 这正是我们在OO设计中试图避免的,一个大的该死的类包含所有东西(UI内容、业务逻辑等等)

根据您的要求,良好的OO设计IMO是:

  • 创建接口IBusniessDAO定义所有方法签名(getUsers、GetChannel等)
  • 创建一个POJO(又名.Plain Old Java Object)类XmlParser实现IBusinessDAO,在这个类中,您可以正常编写方法实现,并且不在这里处理任何异步执行(这不是业务POJO的工作)。这些方法的使用位置和方式(同步或异步)在调用方类(即活动)中确定。如果将来您想用JsonParser替换XmlParser,那么simple create JsonParser将实现IBusinessDAO并替换XmlParser
  • AsyncTask始终保留在Activity中(作为内部类),如果Activity需要网络函数,只需在此Activity中初始化IBusinesDao对象,并在AsyncTask.doInBackground()方法中正确调用网络相关方法,然后在AsyncTask.onPostExecute()方法中直接更新此Activity管理的UI内容

  • 请查看我之前在本文中编写的示例代码,希望这能有所帮助。

    谢谢Christine yep,您提出的第二点正是我在文章中试图表达的,我正在考虑按照您所说的那样将代码封装在“登录屏幕”中PS:关于你的第一点,我还试图让回调开始,因为我确信这是一个很好的方法,我甚至试图从我的登录屏幕实现一个“接口”来实现它。你的建议给了我新的希望,这可能会奏效,所以我会再研究一下。目前,虽然我的代码只是将
    Login.java
    传递给
    ParseXML
    ParseXML>Async
    然后调用
    Login
    中的一个公共方法,说“嘿,我做完了…”。但正如我提到的,我