在Android中,AsyncTask的实用工具类和松耦合请指教 [英] Utility classes in Android, AsyncTask, and loose-coupling please advise

查看:99
本文介绍了在Android中,AsyncTask的实用工具类和松耦合请指教的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图寻找关于这个主题的讨论,但我还没有发现任何有用迄今。因此,我决定继续前进,发布此。

I've attempted to search for any discussion on this topic, but I haven't found anything useful thus far. Therefore, I decided to go ahead and post this.

所以我的查询是关于Android的最佳实践。我创建了一个简单的应用程序,调用REST风格的终点,分析下载的JSON,并显示结果中包含一个活动中的一些片段。

So my query is about Android best practices. I am creating a simple app that calls a RESTful end point, parses the downloaded JSON, and shows the results in some fragments contained within an activity.

我有一个扩展的AsyncTask定制的工具类。在doInBackground方法,我提出的要求,存放在一个字符串,等等。(pretty的简单的东西)的响应。

I have a custom "utility" class that extends AsyncTask. In the doInBackground method, I make the request, store the response in a String, etc. (pretty simple stuff).

现在,我知道有两个方法的AsyncTask的一部分 - 在preExecute和onPostExecute。如果我在网上研究是正确的,这些方法是在那里我应该能够与UI交互,通过传递我的背景下这个工具类,发现按id视图,设置字段文本,或不管它是什么,我想做的。

Now, I understand there are two other methods part of AsyncTask - onPreExecute and onPostExecute. If what I have researched online is correct, these methods are where I should be able to interact with the UI, by passing my context to this utility class, finding the view by id, setting the field text, or whatever it is that I want to do.

这就是我的问题是什么。什么是围绕这个最好的做法?

So that's my question is about. What is the best practice surrounding this?

目前,我的一个扩展的AsyncTask,使Web服务调用有一个私有成员变量实用工具类:

Currently, my utility class that extends AsyncTask and makes the Web service call has a private member variable:

    private FragmentActivity mActivityContext;

然后,与UI交互,我做这样的事情:

And then, to interact with the UI, I do something like this:

@Override
protected  void onPreExecute()
{
    super.onPreExecute();
    android.support.v4.app.FragmentManager fm = mActivityContext.getSupportFragmentManager();
    MainActivity.PlaceholderFragment fragment = (MainActivity.PlaceholderFragment)fm.findFragmentByTag("PlaceholderFragment");

    if (fragment != null)
    {
        TextView textView = (TextView)fragment.getView().findViewById(R.id.my_custom_field);
        textView.setText("This field was updated through onPreExecute!");
    }
}

尽管这似乎工作好了,到目前为止,我关心的是 - 应该在实用程序类是访问它引用了活动的片段经理吗?如果它甚至有一个参考的活动?并利用碎片经理,该实用程序类必须知道片段标记。这不是一个很模块化的或松散耦合的方法。是解决方案简单,只是通过在片段标记,当我创建的实用工具类的实例,而不是具有难以一套像我现在做什么?还是有更好的替代路线?

Although this seems to work okay so far, my concern is - should the utility class be accessing the fragment manager of the activity it has a reference to? Should it even have a reference to the activity? And by using the fragment manager, the utility class has to know the fragment tag. This isn't a very modular or loosely-coupled approach. Is the solution as simple as just passing in the fragment tag when I create the instance of the utility class instead of having it hard set like I do now? Or is there a better alternative route?

推荐答案

这是我做什么,我了解到,从计算器:

This is what I do, I learned that from StackOverflow:

假设我们正在从服务器下载数据库类

Lets say we are downloading categories from the server database

首先,创建一个接口

public interface OnCategoriesDownloadedListener {
    public void onCategoriesDownloadSuccess(ArrayList<String> categories);
    public void onCategoriesDownloadFailure(String reason);
}

然后,在正在等待要下载这些类别的活性,我实现这个接口

then, in the activity that is waiting for those categories to be downloaded, I implement this interface:

public class MyActivity extends Activity implements  OnCategoriesDownloadedListener {

    @Override
    onCategoriesDownloadSuccess(ArrayList<String> categories) {
        //get the categories and do whatever my soul desire
    }

    @Override
    onCategoriesDownloadFailure(String reason) {
       //get the reason and come up with appropriate failure excuse
    }

}

在我的AsyncTask类,我做了以下

in my asynctask class, I do the following

public class GetCategoriesFromServerAsync extends AsyncTask<String, String, ArrayList<String>> {


private OnCategoriesDownloadedListener listener;
private ArrayList<String> categoryNamesArray;
private String reason;

public GetCategoriesFromServerAsync(OnCategoriesDownloadedListener listener) {
    this.listener = listener;
            //usually I pass more data here, for example when Im registering a user in the server database, Im using the constructor to pass their data.
}

@Override
protected ArrayList<String> doInBackground(String... args) {
    int success;

    try {
        //JSON stuff

            return categoryNames;

        } else if (success == 2) {
            reason = "failure";
            return null;
        } else {
            reason = "Connection error";
            return null;
        }
    } catch (JSONException e) {
        e.printStackTrace();
        reason = "Connection error";
        return null;
    }
}

@Override
protected void onPostExecute(Object[] categoryNamesAndLogos) {

    if (listener != null) {
        if (categoryNames!=null) {
            listener.onCategoriesDownloadSuccess(categoryNames);
        } else if (reason.contentEquals(TAG_FAILURE)) {
            listener.onCategoriesDownloadFailure(reason);
        } else if (reason.contentEquals(TAG_CONNECTION_ERROR)) {
            listener.onCategoriesDownloadFailure(reason);
        }

    }
    super.onPostExecute(categoryNames);
}

}

这是一个实现了监听我开始AsyncTask的,使用它的构造活动:

From the activity that implements the listener I start the asynctask, using its constructor:

new GetCategoriesFromDatabase(this).execute();

从而提的是,该活动正在实施监听器,目前正在等待结果。

thus noting that that activity is implementing the listener and is awaiting the results.

在AsyncTask的postExecute我只是处理结果,将其发送到正在等待他们的活动和处理他们在onCategoriesDownloadSuccess方法

In the asynctask postExecute I just deal with the results, send them to the activity that is waiting for them and deal with them in the onCategoriesDownloadSuccess method

如果你想显示一个Loader,你可以做,一起开始从活动的AsyncTask和的onSuccess和onFailure方法端显示出来。此时林这样在上preExecute和的AsyncTask的onPostExecute,但我得需要一定的时间或建议,想想这是更好的方法。

If you want to display a Loader, you can do that alongside starting the asynctask from your activity and end displaying it in the onSuccess and onFailure methods. At this point Im doing this in the onPreExecute and onPostExecute of the AsyncTask, but I gotta take some time or advice and think about which is the better approach.

不知道这是否是最好的做法,因为它是唯一一个我知道,但它肯定对我的作品。

Not sure whether this is a best practice, because its the only one I know but it certainly works for me.

这篇关于在Android中,AsyncTask的实用工具类和松耦合请指教的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆