从AsyncTask Android返回数据

GAM*_*AMA 8 sqlite android android-asynctask

我试图在SO上引用类似的问题,但没有得到任何帮助.

在我的Android应用程序中,我计划实现用户访问过的近期报价,即类似于最近访问过的网页.

以下是我正在遵循的步骤:

1.)每当用户打开任何公司视图时,从数据库中获取公司符号

2.)然后将当前符号与dateTime一起存储在数据库中.

3.)对于从数据库中提取的current value%Change所有符号,获取它们在列表中显示公司名称,当前值和%更改.

问题出现在ASyncTask类中,因为postExecute方法不允许它的返回类型不是void.

我做错了吗?

任何帮助都将是救命!

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;
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

chu*_*ubs 8

postExecute()无法返回值,因为它返回的是谁或什么?您调用AsyncTask的原始方法已经消失,因为您的AsyncTask正在后台运行.当AsyncTask.execute()返回它仍在后台运行时,它是异步的,因此postExecute()不能返回值,因为没有任何东西可以返回它.

相反,您的AsyncTask需要返回您的Activity或其他对象的引用,以便它可以将您的值发布回它.在您的代码中,调用execute()之后的行不能存在,因为您的任务尚未完成.相反,您应该创建一个名为updateSymbol(currentPrice,percentChange)的方法,在那里移动execute()下面的所有代码,并在AsyncTask中传递对Activity的引用.然后从onPostExecute()方法调用updateSymbol(currentPrice,percentChange).

但是,如果你有一个对一个Activity的引用,你可以在doInBackground()运行时将其销毁,并且当postExecute()运行时,它应该只删除结果或不尝试更新UI.例如,用户旋转他们的电话导致活动被销毁.我发现最好在活动中保存对AsyncTask的引用,这样如果活动被销毁,它可以取消()它.您可以调用AsyncTask.cancel()然后检查您的任务是否被取消,如:

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

为所有活动创建基类非常容易,因此您可以轻松跟踪正在运行的AsyncTasks:

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 );
   }
}
Run Code Online (Sandbox Code Playgroud)

一些快速指针.你不需要执行(new String [] {"blah"+ blah}).Java中的Varargs允许您这样做.执行("blah"+ blah).你也正在捕捉异常并继续而不是真正处理它们.当一些事情发生真正发生因为你的应用程序捕获它们时会很难,并且就像没有发生任何事情一样继续.如果出现错误,您可能希望向用户提供一些反馈并停止尝试执行该过程.停止,向用户显示错误,让他们做下一件事.将catch块移动到方法的底部.