在用于读取WebPage的方法之外使用字符串

时间:2014-06-29 12:02:54

标签: android

我使用以下代码阅读网页。

    private class ReadWebPage extends AsyncTask<String, Void, String> {
        public String doInBackground(String... urls) {
            String s = "";
            for (String url : urls) {  
                DefaultHttpClient client = new DefaultHttpClient();
                HttpGet httpGet = new HttpGet(url);
                try {
                    HttpResponse execute = client.execute(httpGet);               
                    InputStream content = execute.getEntity().getContent();
                    BufferedReader buffer = new BufferedReader(
                                                         new InputStreamReader(content));
                    String h = "";
                    while ((h = buffer.readLine()) != null) {
                        s += h;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return s;
        }
    public void onPostExecute (String result) {
    SendingMessage.setText(result);}
    }

我已将代码编辑为其原始状态。为了使问题稍微复杂一些,我想使用String result外部onPostExecute()方法。如果可能,我不想使用AsyncTask,因为我希望每次调用doInBackground(String...urls)时执行不同的任务。通过一次又一次地编写全班(至少三次)使我的代码复杂化。我希望能够使用同一个类。可能吗? 我每次也使用不同的URL。

1 个答案:

答案 0 :(得分:0)

看起来你正在使用AsyncTask类;但是,特别是在错误的语法中,doInBackground()方法只接受一个从task.execute(...)方法传递的变量参数。根据我的描述,您正在尝试从AsyncTask类获取结果/输出以进行进一步处理。在这里,下面是你想要做的演示代码(我只是从我的一些项目中收集它并且应该没问题) -

import java.io.IOException;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.os.AsyncTask;

//NOTE: Create class/inteface in their own file.

// Implement the handler in a activity and pass the reference
// in the custom AsyncTask constructor
public interface TaskResultHandler<TResult>
{
    public void handleResult(TResult result);
}

public class WebPageAsyncTask extends AsyncTask<String, Void, String>
{
    private TaskResultHandler<String> handler = null;
    private StringBuilder resultBuilder = new StringBuilder();

    public WebPageAsyncTask(TaskResultHandler<String> resultHandler)
    {
        this.handler = resultHandler;
    }

    @Override
    protected void onPreExecute()
    {
        super.onPreExecute();
        // Called in UI thread
    }

    @Override
    protected void onPostExecute(String result)
    {
        super.onPostExecute(result);

        // Called in UI thread

        if(handler != null && result != null)
        {
            // Pass the result to the activity
            handler.handleResult(result);
        }

        // Clean reference
        handler = null;
    }

    @Override
    protected void onCancelled(String result)
    {
        // Do not call super

        // Called in UI thread      

        // Result can be null
        if(handler != null && result != null)
        {
            // Pass the result to the activity
            handler.handleResult(result);
        }

        // Clean reference
        handler = null;
    }

    @Override
    protected String doInBackground(String ...urls)
    {
        for(String url : urls)
        {
            // Whether the task is cancelled by the activity/other
            if(this.isCancelled())
            {
                break;
            }

            // NOTE: You can use other approach for HTTP operation; but,
            // it is a workable idea.
            HttpClient client = new DefaultHttpClient();
            ResponseHandler<String> handler = new BasicResponseHandler();
            HttpGet request = new HttpGet(url);
            String result = null;

            try 
            { 
                result = client.execute(request, handler);
                resultBuilder.append(result);
            } 
            catch (ClientProtocolException e) 
            {  
                e.printStackTrace();
            } 
            catch (IOException e) 
            {  
                e.printStackTrace();
            } 
            catch (Exception e) 
            {  
                e.printStackTrace();
            }

            client.getConnectionManager().shutdown();
        }

        // Pass the result to UI thread method onPostExecute()
        return resultBuilder.toString();
    }
}

public class SomeActivity extends Activity implements TaskResultHandler<String>
{
    // How to call
    private void getWebPages(String[] urls)
    {
        // Here, [this] is the class that implemented result handler interface.
        WebPageAsyncTask task = new WebPageAsyncTask(this);

        task.execute(urls);
    }

    // Implemented in activity (or other) to handle result
    public void handleResult(String result)
    {
        // Receive result generated by getWebPages() method.
    }   
}

它应该适用于你的意图。

编辑:AsyncTask文档提供了非常好的信息,说明如果需要取消任务,比如活动被停止或销毁等等。所以,我更新了代码。 AsyncTask应该用于几秒的任务。根据我的经验,在不重写onCancelled(...)方法的情况下,当一个活动在任务完成之前被销毁时,onPostExecute(...)会收到null结果并且很少见。并且传递的活动引用将不在那里,因为GC将清除任务对象(最好在完成后设置为null)。我不认为应该有任何内存泄漏。

第二次编辑:将包含类型的网页网址从URL替换为字符串,因为它在此上下文中运行良好。