Android:在多个Activity中使用AsyncTask

时间:2015-06-29 00:21:44

标签: android android-asynctask

我目前想知道如何在多个Activity中使用AsyncTask而不复制它。

我使用this指南在一个活动中执行此操作并且运行正常。但是在多个Activity中加载和使用这些信息在我看来似乎还有很多工作要做。我试图将我的LoadUrl函数放入另一个类中,然后传递我想要编辑的Textfield。但是当我启动它时,我的应用程序崩溃了。 (我不确定这是否是正确的方法)

public class LoadFromUrl {

public void loadAccountInfo(String key) {

    if( key != null ) {

        new DownloadWebpageTask().execute();

    }
}

private class DownloadWebpageTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {

        // params comes from the execute() call: params[0] is the url.
        try {
            return downloadUrl(urls[0]);
        } catch (IOException e) {
            return "Unable to retrieve web page. URL may be invalid.";
        }
    }

    // onPostExecute displays the results of the AsyncTask.
    @Override
    protected void onPostExecute(String result) {
        //textView.setText(result);
    }

    // Given a URL, establishes an HttpUrlConnection and retrieves
    // the web page content as a InputStream, which it returns as
    // a string.
    private String downloadUrl(String myurl) throws IOException {
        InputStream is = null;
        // Only display the first 500 characters of the retrieved
        // web page content.
        int len = 500;

        try {
            URL url = new URL(myurl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(10000 /* milliseconds */);
            conn.setConnectTimeout(15000 /* milliseconds */);
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            // Starts the query
            conn.connect();
            int response = conn.getResponseCode();
            //Log.d(DEBUG_TAG, "The response is: " + response);
            is = conn.getInputStream();

            // Convert the InputStream into a string
            String contentAsString = readIt(is, len);
            return contentAsString;

            // Makes sure that the InputStream is closed after the app is
            // finished using it.
        } finally {
            if (is != null) {
                is.close();
            }
        }
    }

    // Reads an InputStream and converts it to a String.
    public String readIt(InputStream stream, int len) throws IOException, UnsupportedEncodingException {
        Reader reader = null;
        reader = new InputStreamReader(stream, "UTF-8");
        char[] buffer = new char[len];
        reader.read(buffer);
        return new String(buffer);
    }

}
}

并将其调用:

    @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);

    selectedAccount.setKey("google.com");

    loadUrl.loadAccountInfo(selectedAccount.getKey());

}

我想要做的就是加载URL的信息并使用它来填充我的活动(比如多个TextViews)。每个活动都使用不同的网址和结构。

2 个答案:

答案 0 :(得分:0)

在单独的文件中创建DownloadWebPageTaskpublic class。然后覆盖它的构造函数以传递你需要的任何东西(文本字段,键等)。

答案 1 :(得分:0)

DownloadWebPageTask放在一个单独的类中。然后在onPostExecute中,运行对将更新其UI的活动或片段的回调。这是通过让一个活动实现一个回调来完成的,该回调是DownloadWebpageTask内部的一个内部接口(不必是一个内部接口!)。如您所见,我在代码中添加的内部接口是WebpageCallbacks

这是你在另一个类中的asynctask(间距不完全对不起......):

public class DownloadWebpageTask extends AsyncTask<String, Void, String> {

/**
 * Any activity or fragment that implements WebPageCallbacks
 */
private WebPageCallbacks callbacks;

//start by referencing your activity to call onURLLoaded() for onPostExecute()
public DownloadWebpageTask(WebPageCallbacks callbacks) {
    this.callbacks = callbacks; //note: I think weak references are preferred though
}
//no changes here
@Override
protected String doInBackground(String... urls) {



    // params comes from the execute() call: params[0] is the url.
    try {
        return downloadUrl(urls[0]);
    } catch (IOException e) {
        return "Unable to retrieve web page. URL may be invalid.";
    }
}

// onPostExecute displays the results of the AsyncTask by callback's onURLLoaded()
@Override
protected void onPostExecute(String result) {
    //each activity or fragment will has a method to change their UI
    callbacks.onURLLoaded(result);
}

// Given a URL, establishes an HttpUrlConnection and retrieves
// the web page content as a InputStream, which it returns as
// a string. No changes here
private String downloadUrl(String myurl) throws IOException {
    InputStream is = null;
    // Only display the first 500 characters of the retrieved
    // web page content.
    int len = 500;

    try {
        URL url = new URL(myurl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setReadTimeout(10000 /* milliseconds */);
        conn.setConnectTimeout(15000 /* milliseconds */);
        conn.setRequestMethod("GET");
        conn.setDoInput(true);
        // Starts the query
        conn.connect();
        int response = conn.getResponseCode();
        //Log.d(DEBUG_TAG, "The response is: " + response);
        is = conn.getInputStream();

        // Convert the InputStream into a string
        String contentAsString = readIt(is, len);
        return contentAsString;

        // Makes sure that the InputStream is closed after the app is
        // finished using it.
    } finally {
        if (is != null) {
            is.close();
        }
    }

    /**
     * Any Activity or fragment that implements this will have
     * onURLLoaded() method to update its own UI.
     */
    public interface WebpageCallbacks {

        void onURLLoaded(String result);
    }

}

然后我会将implements DownloadWebpageTask.WebpageCallBacks添加到将使用此asynctask的所有片段和活动中。

这是您的活动:

public class ExampleActivity extends AppCompatActivity implements DownloadWebpageTask.WebpageCallBacks {


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_home);

    selectedAccount.setKey("google.com");
    //changed your oncreate at line below to run your accountInfo
    runAccountInfo(selectedAccount.getKey());
}
    .......................

   //runs the asynctask to load url info from account info like your old loadURLInfo()
   public void runAccountInfo(String key) {

        if( key != null ) {
            //get url with getURL(key)
            new DownloadWebpageTask(this).execute(getURL(key));
        }
    }
    //this will be run from onPostExecute from the asynctask
    @Override
    public void onURLLoaded(String result) {
        textView.setText(result);
    }
}

如果你有时间,我建议不要使用AsyncTask并查看其他库,如rxJava / rxAndroid。我希望这段代码没问题........