带接口

时间:2016-01-20 01:20:21

标签: java android android-asynctask

好的,我必须在这里遗漏一些东西,但我无法将手指放在上面。这是我的情况,我在外部创建我的AsyncTask(良好的实践和可重用),我没有问题连接到服务器,使用onPostExecute();得到我的接口的响应,但从接口的值到Calling类保留这个价值给了我一个问题。这是我的代码示例。

界面

interface getData {
    void done (ArrayList<String> returnedData);
}

使用名为serverRequests

的包装类的AsyncTask和调用方法
public void getDataInBackground ( String params, getData retData){
    new getDataAsync(params,retData).execute();
}
public class getDataAsync extends AsyncTask<Void,Void,ArrayList<String>> {
    String params;
    getData retData;
    public getDataAsync( String params, getData retData){
        this.params=params;
        this.retData=retData;
    }
     @Override
    protected ArrayList<String> doInBackground(Void... params) {
        ArrayList<String> list = new ArrayList<>();
        //Do a bunch of stuff that connects to my server
        return list;
    }
    @Override
    protected void onPostExecute(ArrayList<String> returnedData) {
        retData.done(returnedData);
        super.onPostExecute(returnedData);
    }
}

然后调用此过程的Activity类就是这样。

public class MyActivity extends AppCompatActivity {
    ServerRequests serverRequests; // the Wrapper class to call my different AsyncTasks
    ArrayList<String> someList;
    String params="some kind of params";

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

    serverRequests= new serverRequests(this);//this being the context passed
    someList=new ArrayList<>();

     serverRequests.getDataInBackground(params, new getData() {
        @Override
        public void done(ArrayList<String> returnedData) {
            someList.addAll(returnedData);
            //somelist has data here
            //used AlertDialogs to confirm data
        }
    });
    //someList is empty here and data is needed to perform other tasks.
    // again used AlertDialogs to confirm data

现在,在此活动中,我会为最终用户执行其他几个AsyncTasks收集数据。其他任务数据取决于第一次调用。我曾想过暂时将数据存储在手机上,然后我想起了我的妻子,他的手机总是受限于内存空间,这可能会产生不必要的错误。我想在这个内部执行其他AsyncTask,但后来我会不必要地打开多个线程并在手机上浪费CPU。我已经尝试过我在这个网站上找到的其他建议,比如制作someList静态/最终,但这也没有。我还尝试了一个简单的赋值someList = returnedData。那么有关如何从AsyncTask获取此值并进入调用方法的任何建议?

3 个答案:

答案 0 :(得分:1)

界面正在运作。

//access download task data
public interface MyAccessResponse {
    void postResult(String asyncResult);
}

//download class
public class DownloadTask extends AsyncTask<String, Void, String> {


    public MyAccessResponse delegate=null;
    public DownloadTask(MyAccessResponse asyncResponse) {
        delegate = asyncResponse;//Assigning call back interfacethrough constructor
    }


    @Override
    protected String doInBackground(String... urls) {

        URL url;
        HttpURLConnection urlConnection = null;

        try {
            //read 1st string
            url = new URL( urls[0] );
            urlConnection = (HttpURLConnection) url.openConnection();

            InputStream inpt = urlConnection.getInputStream();

            BufferedReader reader = new BufferedReader(new InputStreamReader(inpt));
            StringBuilder builder = new StringBuilder();
            String aux = "";

            while ((aux = reader.readLine()) != null) {
                builder.append(aux);
            }
            return builder.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    @Override
    protected void onPostExecute(String result) {

        Log.i("tms delegate", "access delegate");

        //super.onPostExecute(result);
        if(result!=null && delegate!=null)
        {
            delegate.postResult(result);
        } else {
            Log.i("MyAccess", "You have not assigned IApiAccessResponse delegate");
        }
    }
} //end of Download Task

在onCreate中: ...

    DownloadTask task =  new DownloadTask(new MyAccessResponse() {

        @Override
        public void postResult(String asyncResult) {
            //html = asyncResult ;
            //Log.i("tms postResult", html);
            //process result--split point: "/imgs/hr_shadow.gif"
            String[] splitResult = asyncResult.split("/imgs/hr_shadow.gif");

            //example: <img src="/celebs/rihanna/thumbs/thumb1.jpg" alt="Rihanna" height="95" width="95" border="0" />
            Pattern p = Pattern.compile("src=\"(.*?)\"");
            Matcher m = p.matcher(splitResult[1]);
            while(m.find()) {
                celebURLs.add( m.group(1));
                Log.i("tms src:", m.group(1));
            }

            p = Pattern.compile("alt=\"(.*?)\"");
            m = p.matcher(splitResult[1]);
            while(m.find()) {
                celebNames.add( m.group(1));
                Log.i("tms name:", m.group(1));
            }

            createNewQuestion();
        }
    });

答案 1 :(得分:0)

如果第二个取决于第一个的结果,那么在第一个的onPostExecute中运行第二个AsyncTask是完全可以接受的。你真的不应该担心多个线程 - 首先关闭AsyncTasks都在一个线程上排队,除非你明确要求否则。其次,您的任务很可能是IO绑定的。第三,与GPS和显示器相比,CPU的使用量是一个微小的电池消耗量 - 你几乎不得不尝试用它来消除它。

答案 2 :(得分:0)

我找到了答案。在activity类中,我创建了一个void方法来设置与上下文相比较的值。然后当我得到我的价值时,我把它发送到那个方法。这是一个例子。

protected void setValue(ArrayList<String> list){
     this.someList=list;}

然后在我原来的课堂活动中

someList.addAll(returnedData);

我用

替换了它
setValue(returnedData);

这样就可以通过整个班级来获取价值