AsyncTask 和 InputStream 的 Android 问题 [英] Android issues with AsyncTask and InputStream

查看:15
本文介绍了AsyncTask 和 InputStream 的 Android 问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经尝试自己解决这个问题很长一段时间了..通过反复试验/错误以及研究,但我似乎无法弄清楚.我对 Async 和网络连接以及 stuch 很不满意,所以这可能很简单,我正在寻找.无论如何...我将粘贴一些相关的代码示例和解释.

I've been trying to figure this out on my own for quite a while.. by trial/error as well as research, but I just can't seem to get it figured out. I'm pretty bad with Async and network connections and stuch, so it might be something simple that I'm over looking. Anyway... I'll paste some relevant code samples and explanations.

我的问题的快速背景.我正在为我的应用程序使用 Rotten Tomatoes API,并且正在使用 GSON 来解析他们的数据.我最初的目标是 2.3,这很好用.然后我决定支持ICS,当然也遇到了UI线程没有网络操作"的问题——于是我开始深入研究AsyncTask.

Quick background of my problem. I'm working with the Rotten Tomatoes API for my app, and am using GSON for the parsing of their data. I was initially targeting 2.3, and this worked fine. Then I decided to have support for ICS, and of course ran into the "no network operation on the UI thread" - so I started to delve into AsyncTask.

这是我的 InputStream 方法:

Here is my InputStream method:

private InputStream retrieveStream(String url) {

    DefaultHttpClient client = new DefaultHttpClient();

    HttpGet getRequest = new HttpGet(url);

    try {

        HttpResponse getResponse = client.execute(getRequest);
        final int statusCode = getResponse.getStatusLine().getStatusCode();

        if (statusCode != HttpStatus.SC_OK) {
            Log.w(getClass().getSimpleName(),
                    "Error " + statusCode + " for URL " + url);
            return null;
        }

        HttpEntity getResponseEntity = getResponse.getEntity();
        return getResponseEntity.getContent();
    }
    catch (IOException e) {
        getRequest.abort();
        Log.w(getClass().getSimpleName(), "Error for URL " + url, e);
    }

    return null;
}

在我的主要活动中运行良好,现在在尝试将其转换"为 AsyncTask 时出现问题.我一直这样称呼它:

Which was working fine in my main activity, and now is giving me issues when trying to 'convert' it into AsyncTask. I've been calling it like this:

InputStream source = retrieveStream( url parameter );

然后我尝试将该方法移动到我的 AsyncTask 类中,并像这样调用它:

Then I tried moving that method into my AsyncTask class, and calling it like this:

private PerformMovieSearch performSearch = new PerformMovieSearch(this);
InputStream source = performSearch.retrieveStream(movieQueryUrl);

但这并不能解决问题,仍然会出现关于在 UI 上执行网络操作的错误.我需要弄清楚的是如何从我猜的 AsyncTask 中调用retrieveStream".目前该类看起来像这样:

But that doesn't cut it, still get the error about performing network actions on the UI. What I need to figure out is how to call 'retrieveStream' from the AsyncTask I guess. Currently that class looks like this:

package net.neonlotus.ucritic;

[imports]

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

private final Context context;
private ProgressDialog progressDialog;


public PerformMovieSearch(Context context){
    this.context = context;
}


@Override
protected String doInBackground(String... urls) {
    retrieveStream(urls[0]);

    return null;

}

@Override
protected void onPreExecute() {
    progressDialog= ProgressDialog.show(context, "Please Wait","Searching movies", true);

}


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

    MyActivity.mListAdapter.notifyDataSetChanged();
}

public InputStream retrieveStream(String url) {

    DefaultHttpClient client = new DefaultHttpClient();
    HttpGet getRequest = new HttpGet(url);

    try {
        HttpResponse getResponse = client.execute(getRequest);
        final int statusCode = getResponse.getStatusLine().getStatusCode();

        if (statusCode != HttpStatus.SC_OK) {
            Log.w(getClass().getSimpleName(),
                    "Error " + statusCode + " for URL " + url);
            return null;
        }

        HttpEntity getResponseEntity = getResponse.getEntity();
        return getResponseEntity.getContent();
    } catch (IOException e) {
        getRequest.abort();
        Log.w(getClass().getSimpleName(), "Error for URL " + url, e);
    }

    return null;
}

}

doinbackground"是需要改变的......但我似乎无法找到一种直接的方法来让它正常工作.我正在使用

The "doinbackground" is what needs to be changed... but I can't seem to find a straight way to get that working properly. I was executing using

new PerformMovieSearch(this).execute(movieQueryUrl);

我知道这有很多东西,可能会令人困惑……但是如果有人知道如何从本质上异步执行retrieveStream方法,那就太好了.就像我说的,我尝试了很多东西,做了很多研究,只是想不出任何有用的东西.

I know that is a lot of stuff, potentially confusing... but if anybody knows how to essentially do the retrieveStream method asynchronously, that would be great. Like I said, Ive tried many things, did plenty of research, just could not come up with anything useful.

推荐答案

重点是,你没有理解 asynctask 是如何工作的!

the point is, you didn't understand how asynctask works!

您必须阅读流程和线程指南:http://developer.android.com/guide/components/processes-and-threads.html

You MUST read the guide Processes and Threads: http://developer.android.com/guide/components/processes-and-threads.html

好吧,让我试着帮助你.

But ok, let me try help you.

在 doInBackground 上,您正确地调用了方法retrieveStream,但是您没有对流做任何事情.因此,您必须处理流,然后返回它.正如你所说的,你期待一个 JSON,我假设你会收到一个字符串,所以你的retrieveStream 的代码应该是这样的:

On doInBackground you are correctly calling the method retrieveStream, but you are doing nothing with the stream. So, you have to process the stream and then, return it. As you said you are expecting an JSON, I'm assuming you will receive a String, so the code of your retrieveStream should like this:

public String retrieveStream(String url) {

    DefaultHttpClient client = new DefaultHttpClient();
    HttpGet getRequest = new HttpGet(url);

    try {
        HttpResponse getResponse = client.execute(getRequest);
        final int statusCode = getResponse.getStatusLine().getStatusCode();

        if (statusCode != HttpStatus.SC_OK) {
            Log.w(getClass().getSimpleName(),
                    "Error " + statusCode + " for URL " + url);
            return null;
        }

        HttpEntity getResponseEntity = getResponse.getEntity();
        String jsonString = EntityUtils.toString(getResponseEntity);
        return jsonString;
    } catch (IOException e) {
        getRequest.abort();
        Log.w(getClass().getSimpleName(), "Error for URL " + url, e);
    }

    return null;
}

看,我将返回类型更改为 String.也许,您应该将名称更改为retrieveMoviesJSON 或类似的名称.

Look that I changed the return type to String. And maybe, you should change the name to retrieveMoviesJSON or something like this.

你应该把你的 AsyncTask 改成这样:

And you should change your AsyncTask to something like this:

class PerformMovieSearch AsyncTask<String, Void, ArrayList<Movie>>() {

            @Override
            protected void onPreExecute() {
                progressDialog= ProgressDialog.show(context, "Please Wait","Searching movies", true);
            }

            @Override
            protected ArrayList<Movie> doInBackground(String... params) {
                String moviesJson = retrieveStream[params[0]];
                JSONObject moviesJson = new JSONObject(moviesJson);
                ArrayList<Movie> movies = new ArrayList<Movie>();
                /*
                 * Do your code to process the JSON and create an ArrayList of films.
                 * It's just a suggestion how to store the data.
                 */
                return movies;
            }

            protected void onPostExecute(ArrayList<Movie> result) {
                progressDialog.dismiss();
                //create a method to set an ArrayList in your adapter and set it here.
                MyActivity.mListAdapter.setMovies(result);
                MyActivity.mListAdapter.notifyDataSetChanged();
            }
        }

你可以像以前一样打电话.

And you can call as the same way you were doing.

清楚了吗?需要更多解释吗?

Is it clear? Need more explanation?

[]s内托

这篇关于AsyncTask 和 InputStream 的 Android 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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