从AsyncTask的Andr​​oid的返回数据 [英] Return data from AsyncTask Android

查看:147
本文介绍了从AsyncTask的Andr​​oid的返回数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想引用类似的问题上如此,但并没有得到任何帮助。

在我的Andr​​oid应用程序,我打算执行最近报价的用户访问,即类似于在网站最近访问过的网页。

以下是我下面的步骤:

1。)每当用户打开任何一家公司认为,从数据库中获取的公司符号

2。)然后点击保存当前符号随着日期时间在数据库中。

3)对于从数据库中读取的所有符号,取他们的电流值%更改 和显示的公司名称,当前值和百分比变化在列表中。

的AsyncTask 类的问题就出现了以 postExecute 方法不允许它的返回类型是其他任何比无效

难道我做错什么?

任何帮助将是生命的救星!

 的String [] rsym,加拿大皇家骑警,RCHG;
RDBM =新RecentDBManager(CompanyView.this);
尝试 {
日历日期1 = Calendar.getInstance();
SimpleDateFormat的dateformatter =新的SimpleDateFormat(
                            DD / MM / YYYY HH:MM:SS);

串的currentdate = dateformatter.format(date1.getTime());

rdbM.openDB();

//步骤1
rsym = rdbM.getRecent_sym();

//第2步
rdbM.setData(currentsymbol,的currentdate);

rdbM.closeDB();

}赶上(例外五){
抛出新的错误(***错误的DB访问***+ e.toString());
}

 //第3步
        的for(int i = 0; I< rsym.length;我++)
        {
            DownloadRecentQuote quotetask =新DownloadRecentQuote();
            recentquotetask
            .execute(新的String [] {http://abc.com/stockquote.aspx?id=
                        + rsym [I]});

 //当前值和百分比变化应当从AsyncTask的类返回

            RCMP [I] = valuearr [0];
            RCHG [I] = valuearr [1];
            }

            List1中=新的ArrayList< HashMap的<字符串,字符串>>();
            HashMap的<字符串,字符串> addList1;

            的for(int i = 0; I<限制;我++)
            {
                addList1 =新的HashMap<字符串,字符串>();
                addList1.put(RecentSym_COLUMN,rsym [I]);
                addList1.put(RecentCMP_COLUMN,加拿大皇家骑警[I]);
                addList1.put(RecentChg_COLUMN,RCHG [I]);

                list1.add(addList1);

                RecentAdapter适配器1 =新RecentAdapter(
                    CompanyView.this,CompanyView.this,List1中);
                listrecent.setAdapter(适配器1);
            }


私有类DownloadRecentQuote扩展的AsyncTask<字符串,太虚,字符串> {
    / *获取数据的RecentQuote信息* /
    @覆盖
    保护字符串doInBackground(字符串...网址){
        串响应=;
        对于(字符串网址:网址){
            DefaultHttpClient客户端=新DefaultHttpClient();
            HTTPGET HTTPGET =新HTTPGET(URL);
            尝试 {
                HTT presponse执行= client.execute(HTTPGET);
                InputStream的内容= execute.getEntity()的getContent()。

                的BufferedReader缓冲=新的BufferedReader(
                        新InputStreamReader的(内容));
                字符串s =;
                而((S = buffer.readLine())!= NULL){
                    响应+ = S;
                }

            }赶上(例外五){
                e.printStackTrace();
            }
        }
        返回响应;
    }

    @覆盖
    保护无效onPostExecute(字符串结果){

        ARR1 = result.split(@);

        如果(ARR1 [0] .length()!= 0){

            如果(ARR1 [0] .equals(1)){

                改编= ARR1 [1] .split(;);

            //返回2 STRINGS
                            字符串valuearr [];
                valuearr [0] =改编[3];
                valuearr [1] =改编[6] .concat(%);
                //返回valuearr;
            }
        }
    }
 

解决方案

postExecute()不能返回一个值,因为谁或什么将其退回?去调用该AsyncTask的你原来的方法,因为你的AsyncTask是在后台运行。这是异步的含义时AsyncTask.execute()返回它仍然在后台运行,因此postExecute()不能返回一个值,因为没有什么交回。

而不是你的AsyncTask需要引用回到你的活动或其他对象,因此它可以发布你的价值观回去吧。在您的$ C C线$后,调用execute()不能在那里,因为你的任务还没有完成。相反,你应该创建一个名为updateSymbol(currentPrice,percentChange)方法,将下面所有的code的execute()在那里,并在您的AsyncTask你应该传递一个参考的活动。然后调用updateSymbol(currentPrice,percentChange)从onPostExecute()方法。

不过,要小心,如果你有一个参考回到一个活动也可以在您的doInBackground被销毁()正在运行,而当postExecute()运行时,它应该只是下降的结果还是不尝试更新的用户界面。例如,用户旋转他们的电话使活性被破坏。我觉得最好的举行提到的AsyncTask的活动,这样就可以取消(),如果该活动被破坏。您可以拨打AsyncTask.cancel(),然后检查你的任务被取消,如:

 公共无效postExecute(字符串结果){
    如果(!isCanceled()){
       //做你的更新在这里
       activity.setSymbol(结果);
    }
}
 

这真的很容易地创建一个基类中的所有活动,因此您可以轻松地跟踪运行AsyncTasks的:

 公共类BaseActivity延伸活动{

   名单< AsyncTask的> runningTasks;

   公共无效的onStop(){
       对于(AsyncTask的任务:runningTasks){
          task.cancel(真正的);
       }
   }

   公共AsyncTask的开始(AsyncTask的任务){
      runningTasks.add(任务);
      返回任务;
   }

   公共无效完成(AsyncTask的任务){
      runningTasks.remove(任务);
   }
}
 

一些简单的指针。你不需要执行(新的String [] {嗒嗒+等等})。可变参数在Java中允许你这样做。执行(嗒嗒+等等)。也正赶上异常和持续没有真正处理它们。这将是很难当事情真的发生了,因为你的应用程序捉住他们,只是继续仿佛什么都没有发生。如果你得到一个错误,你可能想提供一些反馈给用户,并停止试图执行这一进程。停止,显示错误给用户,让他们做下的事情。将catch块到方法的底部。

I tried to refer similar question on SO, but didn't got any help.

In my android app, I'm planning to implement Recent Quote the user has visited i.e. similar to recently visited pages on web.

Following are the steps I'm following:

1.) Whenever user opens any company view, fetch the company symbols from database

2.) Then store the current symbol along with dateTime in database.

3.) For all symbols fetched from database, Fetch their current value and %Change and display Company name, current value and %Change in a list.

The problem arises in the ASyncTask class as postExecute method doesn't allow it's return type to be any other than void.

Am I doing anything wrong?

Any help will be life saver !!!

String[] rsym,rcmp,rchg;
rdbM = new RecentDBManager(CompanyView.this);
try {
Calendar date1 = Calendar.getInstance();
SimpleDateFormat dateformatter = new SimpleDateFormat(
                            "dd/MM/yyyy HH:mm:ss");

String currentdate = dateformatter.format(date1.getTime());

rdbM.openDB();

//STEP 1
rsym = rdbM.getRecent_sym();

//STEP 2                
rdbM.setData(currentsymbol, currentdate);

rdbM.closeDB();

} catch (Exception e) {
throw new Error(" *** ERROR in DB Access *** "+ e.toString());
}

 //STEP 3
        for(int i=0;i<rsym.length;i++)
        {
            DownloadRecentQuote quotetask = new DownloadRecentQuote();
            recentquotetask
            .execute(new String[] { "http://abc.com/stockquote.aspx?id="
                        + rsym[i] });

 //CURRENT VALUE and %CHANGE which should be returned from ASyncTask class

            rcmp[i]=valuearr[0];
            rchg[i]=valuearr[1];
            }

            list1 = new ArrayList<HashMap<String, String>>();
            HashMap<String, String> addList1;

            for (int i = 0; i < limit; i++) 
            {
                addList1 = new HashMap<String, String>();
                addList1.put(RecentSym_COLUMN, rsym[i]);
                addList1.put(RecentCMP_COLUMN, rcmp[i]);
                addList1.put(RecentChg_COLUMN, rchg[i]);

                list1.add(addList1);

                RecentAdapter adapter1 = new RecentAdapter(
                    CompanyView.this, CompanyView.this, list1);
                listrecent.setAdapter(adapter1);
            }


private class DownloadRecentQuote extends AsyncTask<String, Void, String> {
    /* Fetching data for RecentQuote information */
    @Override
    protected String doInBackground(String... urls) {
        String response = "";
        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 s = "";
                while ((s = buffer.readLine()) != null) {
                    response += s;
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return response;
    }

    @Override
    protected void onPostExecute(String result) {

        arr1 = result.split("@");

        if (arr1[0].length() != 0) {

            if (arr1[0].equals("1")) {

                arr = arr1[1].split(";");

            //RETURN 2 STRINGS
                            String valuearr[];
                valuearr[0] = arr[3];
                valuearr[1] = arr[6].concat("%");
                //return valuearr;
            }
        }
    }

解决方案

postExecute() can't return a value because who or what would it return to? Your original method that invoked the AsyncTask is gone because your AsyncTask is running in the background. It's asynchronous meaning when AsyncTask.execute() returns it's still running in the background, and hence postExecute() can't return a value because there's nothing to return it to.

Instead your AsyncTask needs a reference back to your Activity or some other object so it can post your values back to it. In your code the lines after you call execute() can't be there because your task hasn't finished. Instead you should create a method called updateSymbol( currentPrice, percentChange), move all that code below execute() in there, and in your AsyncTask you should pass a reference to the Activity. Then call updateSymbol( currentPrice, percentChange ) from the onPostExecute() method.

But, be careful if you have a reference back to an Activity it can be destroyed while your doInBackground() is running, and when postExecute() runs it should just drop the results or not attempt to update the UI. For example, the user rotates their phone causing the Activity to be destroyed. I find it best to hold a reference to the AsyncTask in the activity so it can cancel() it if the Activity is destroyed. You can call AsyncTask.cancel() then check if your task was canceled like:

public void postExecute( String result ) {
    if( !isCanceled() ) {
       // do your updating here
       activity.setSymbol( result );
    }
}

It's really easy to create a base class for all Activities so you can easily keep track of AsyncTasks running:

public class BaseActivity extends Activity {

   List<AsyncTask> runningTasks;

   public void onStop() {
       for( AsyncTask task : runningTasks ) {
          task.cancel(true);
       }
   }

   public AsyncTask start( AsyncTask task ) {
      runningTasks.add( task );
      return task;
   }

   public void done( AsyncTask task ) {
      runningTasks.remove( task );
   }
}

Some quick pointers. You don't need execute( new String[] { "blah" + blah } ). Varargs in Java allow you to do this. execute( "blah" + blah ). You also are catching exceptions and continuing without really handling them. It will be hard when something really happens because your app catches them, and just continues as if nothing happened. If you get an error you might want to provide some feedback to the user and stop trying to execute that process. Stop, show an error to the user, and let them do the next thing. Move the catch blocks to the bottom of the methods.

这篇关于从AsyncTask的Andr​​oid的返回数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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