【问题标题】:Convert android AsyncTask call to a separate class and call from all activities将 android AsyncTask 调用转换为单独的类并从所有活动中调用
【发布时间】:2013-05-13 08:15:46
【问题描述】:

我是安卓开发新手。我的应用程序中有一个 AsyncTask 函数。从所有活动中调用 http 请求。现在在每个活动中我都使用以下类连接到服务器,在某些活动中我什至调用了两次!!。

基本上我是一名网络开发人员,在这种情况下,我们使用一个可以从整个应用程序(网络)访问的类,并使用通用函数来执行相同的活动。唯一的区别是输入和输出会改变。

我怀疑在这种情况下我可以使用(转换)这个到这样的函数或类吗? 我的假设是

  1. 创建一个android类(可以从所有activity中访问)
  2. 只需使用特定服务器(用于服务器中的进程)制作我们需要的 JSON 字符串
  3. 只需将创建的json传递给创建的类,然后进行http连接)
  4. 处理服务器返回的数据
  5. 将其传递给相应的活动

这样我就可以对所有活动使用相同的功能,并且可以避免重复查询

我可以把这段代码转换成这样的方式吗?

我的代码

public class MainActivity extends Activity {




    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        setContentView(R.layout.activity_main);

                LogIN loginUser = new LogIN();
        LoginUser.execute("");


}

         private class LogIN extends AsyncTask<String, Integer, String> {


        @Override
        protected String doInBackground(String... sUrl) {
            try {


        String path = "http://www.domain_name.com/app/checkSession.php";

        HttpClient client = new DefaultHttpClient();
        HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); 

                HttpResponse response;
                JSONObject json = new JSONObject();
                try {
                    HttpPost post = new HttpPost(path);
                    json.put("access_token", "123456");


                    post.setHeader("json", json.toString());
                    StringEntity se = new StringEntity(json.toString());
                    se.setContentEncoding((Header) new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
                    post.setEntity(se);

              response = client.execute(post);
                    /* Checking response */
                    if (response != null) {
                        InputStream in = response.getEntity().getContent(); 

                        String a = convertStreamToString(in);

                        JSONObject jsono = stringToJsonobj(a);
                        String passedStringValue = jsono.getString("result");

                        if(passedStringValue.equals("1")){
                            flags=1;
                            //Log.v("TAGG", "Success");
                        }
                        else {
                            flags=0;
                            //Log.v("TAGG", "Failed !");
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }








            } catch (Exception e) {
            }
            return null;
        }

        @Override
        protected void onPreExecute() {


            super.onPreExecute();
            showDialogue("Login Processing", "Loading");
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
            super.onProgressUpdate(progress);
        }

        @Override
        protected void onPostExecute(String result) {
            if(flags.equals(1)){
            Itent homepage = new Intent(MainActivity.this, RegisterDevice.class);
            startActivity(homepage);
            finish();
            }
            else {
                Intent homepage = new Intent(MainActivity.this, LoginActivity.class);
                startActivity(homepage);
                finish();
            }
            super.onPostExecute(result);
        }

    }

}

请任何人帮助/建议 提前致谢

【问题讨论】:

  • 您总是可以将 Login 声明为一个类,只需将类文件命名为“Login”,然后将所有异步任务代码移至其中
  • 最简单的方法是将Activity类型的参数传递给Login类的构造函数。所以你可以从你的任务中调用startActivityfinish等方法。

标签: android web-services android-layout android-intent


【解决方案1】:

将你的类解压到另一个文件并公开

    public class LogIN extends AsyncTask<Object, Integer, String> {
        private ILoginListener listener;

        @Override
        protected String doInBackground(Object... arg0) {
            try {
               this.listener = (ILoginListener) arg0[0];
              //You can also send the url in the obj array
              String theUrl = (String) arg0[1];


        String path = "http://www.domain_name.com/app/checkSession.php";

        HttpClient client = new DefaultHttpClient();
        HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); 

                HttpResponse response;
                JSONObject json = new JSONObject();
                try {
                    HttpPost post = new HttpPost(path);
                    json.put("access_token", "123456");


                    post.setHeader("json", json.toString());
                    StringEntity se = new StringEntity(json.toString());
                    se.setContentEncoding((Header) new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
                    post.setEntity(se);

              response = client.execute(post);
                    /* Checking response */
                    if (response != null) {
                        InputStream in = response.getEntity().getContent(); 

                        String a = convertStreamToString(in);

                        JSONObject jsono = stringToJsonobj(a);
                        String passedStringValue = jsono.getString("result");

                        if(passedStringValue.equals("1")){
                            flags=1;
                            //Log.v("TAGG", "Success");
                        }
                        else {
                            flags=0;
                            //Log.v("TAGG", "Failed !");
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }








            } catch (Exception e) {
            }
            return null;
        }

        @Override
        protected void onPreExecute() {


            super.onPreExecute();
            showDialogue("Login Processing", "Loading");
        }

        @Override
        protected void onProgressUpdate(Integer... progress) {
            super.onProgressUpdate(progress);
        }

        @Override
        protected void onPostExecute(String result) {
            listener.logInSessionCheckListener(flag.equals(1));
            super.onPostExecute(result);
        }

    }

关于你的其他问题,我通常有一个界面,如下所示:

    public interface ILoginListener {

        public void logInSessionCheckListener(SomeNeeded Value);

     }

我在需要 postExecute 结果的类中实现接口,并在覆盖的方法中实现你想要的任务结果。 您使用它的类将如下所示:

public class SomeClass implements ILoginListener { 

    //Call it like this from any class:

    LogIN loginTask = new LogIn();

    Object[] someParams = new Object[2]; 
    //add the listener
    someParams[0] = SomeClass.this
    //add the url 
    someParams[1] = someUrlString;

    loginTask.execute(someParams);

   @Override
   public void logInSessionCheckListener(SomeNeeded Value){
    //do Stuff with your results

   }
}

【讨论】:

  • 将添加答案给我一个秒
  • 所以现在想想我在那里,请使用带有侦听器和 url 的 obj 数组调用 asyntask,您可以检查代码,并询问您是否不理解。玩得开心
  • 是的,为此使用监听器,在接口上更改方法中的参数,以便您可以获取(json数组,json对象)或任何您需要的东西
  • 所以我添加了你的班级应该是什么样子,也许现在你会更清楚
  • 是的,该文件将被称为“ILLoginListener.java”,在那里你复制代码
【解决方案2】:

您可以这样做,就像为 doInBackground() 方法中的所有内容创建单独的类,并在所有活动中调用它,并将参数传递给

   LogIN loginUser = new LogIN(yourparameter);
    LoginUser.execute("");

并检查 AsyncTask 类构造函数中的参数,如

 public LogIN(Myparameter){
        // Your data
      }

【讨论】:

    【解决方案3】:

    另一方面,您可以使用这个出色的 android 框架:android-queryasync API。 它允许您从活动执行异步网络任务,并轻松处理您的请求结果。

    【讨论】:

      【解决方案4】:

      您应该使用接口来实现对您的 ui 活动的回调。 看看这个线程,它可能有用: android asynctask sending callbacks to ui 并且您的 asyntask 类应该位于具有公共访问权限的单独 java 文件中。

      要传递参数,您只需像这样调用一个新的 LogIN 异步任务:

      new LogIN().execute(urls);
      

      希望对您有所帮助:)

      【讨论】:

        【解决方案5】:

        请记住,您永远无法知道 AsyncTask 何时结束。因此,如果您使用它来验证用户,然后执行任务 X、任务 Y 或任务 Z,

        那么也许最好创建一个登录助手类

        公共类 LoginHelper {

        public boolean login(params){
            // Authenticate user and return true if successfull
        }
        

        }

        然后在你的 Activity 类中添加

        私有类 X 扩展 AsyncTask {

        @Override
        protected String doInBackground(String... sUrl) {
        
            ...
            boolean authenticated = LoginHelper.login(params...);
        
            if(authenticated == true) {
                // Perform task X here...
            } else {
                // Inform the user that the login failed...
            }
        

        }

        【讨论】:

          【解决方案6】:

          首先 您必须传递调用异步任务的上下文

          示例代码

          Login loginTask = new Long(getContext());
          loginTask.execute();
          

          你的登录类应该有一个接受上下文的构造函数

          示例代码

          public class Login extends AsyncTask<String, Integer, String> {
          
          private Context mContext ;
          private ProgressDialog pd; 
          private Handler handler = new Handler { };
          public Login (Context context){
          mContext = context ;
          }
          .....
          

          然后确保在 Login 类中创建方法 showDialog 来显示进度对话框

          注意 您可以添加您需要的任何构造函数来自定义登录任务的行为 例如:传递布尔参数来告诉登录任务是可取消的......

          希望对你有帮助:)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-06-01
            • 1970-01-01
            • 1970-01-01
            • 2016-06-08
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多