简体   繁体   English

Android AsyncTask确保所有数据均已加载

[英]Android AsyncTask making sure all data has been loaded

Hi I'm trying to create an Asynctask that runs two functions and when they are done loading it then fills the UI with the data. 嗨,我正在尝试创建一个运行两个函数的Asynctask,当它们完成加载后,然后用数据填充UI。 at the moment for somereason it only fills the UI with data from one of the Functions and its which ever of the functions finishes loading first. 目前,出于某种原因,它仅用一个函数中的数据填充UI,并且其中任何一个函数首先完成加载。

For Example 例如

i have two functions LoadNewsFeed() and LoadResultsFeed() at the moment loadResultsFeed() shows the data and not anything from loadNews() however if i comment out LoadResultsFeed() the data from loadNews fills The UI but not from loadResultsFeed 当loadResultsFeed()显示数据而不显示loadNews()时,我有两个函数LoadNewsFeed()和LoadResultsFeed(),但是如果我注释掉LoadResultsFeed(),则来自loadNews的数据将填充UI,但不会填充来自UI的数据。

is there a way i could set it to if that one is finished loading, load the other than perform the FillData() function? 有没有一种方法可以将其设置为如果完成加载,再加载另一个而不执行FillData()函数?

heres what i have so far 这是我到目前为止的

public class PostTask extends AsyncTask { 公共类PostTask扩展了AsyncTask {

    @Override
    protected Boolean doInBackground(Void... params) {
        boolean result = false;

        loadNewsFeed();

        publishProgress("method1");
        loadResultsFeed();
        publishProgress("method2");
        return result;
    }


    protected void onProgressUpdate(String... progress) {
        StringBuilder str = new StringBuilder();
            for (int i = 1; i < progress.length; i++) {
                str.append(progress[i] + " ");

            }
    }

        @Override
    protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);
        Log.v("BGThread", "begin fillin data");
         FillData();
    }
}

heres my FillData() Function 这是我的FillData()函数

public void FillData(){ 


     if (ChosenMethod.equals("Team")) {




        arrayAdapter = new ArrayAdapter<String>(this, R.layout.single_item, newsList);

         String[] mStrings = (String[]) imageList.toArray(new String[imageList.size()]);
         String[] news = (String[]) newsList3.toArray(new String[newsList3.size()]);

         arrayAdapter3 = new LazyAdapter(this, mStrings, news);


            ListView list = getListView();
               list.setTextFilterEnabled(true);

               LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE );
                View header = inflater.inflate( R.layout.homeheader, list, false);
                View header2 = inflater.inflate( R.layout.homeheader2, list, false);
                View header3 = inflater.inflate( R.layout.homeheader3, list, false);


        //setListAdapter (arrayAdapter);

                 resultsView = LayoutInflater.from(getBaseContext()).inflate(R.layout.resultscell,
                         null);

               TextView homeTeam = (TextView) resultsView.findViewById(R.id.HomeTeam);
               homeTeam.setText(HomeTeam);

               TextView awayTeam = (TextView) resultsView.findViewById(R.id.AwayTeam);
               awayTeam.setText(AwayTeam);

               TextView homeScore = (TextView) resultsView.findViewById(R.id.HomeScore);
               homeScore.setText(HomeScore);

               TextView awayScore = (TextView) resultsView.findViewById(R.id.AwayScore);
               awayScore.setText(AwayScore);

               TextView attendance = (TextView) resultsView.findViewById(R.id.Attendence);
               attendance.setText("Att:" + Attendance);

               TextView division = (TextView) resultsView.findViewById(R.id.Division);
               division.setText(Division);

               Log.v("BGThread", "Filled results");

            adapter = new MergeAdapter();
            adapter.addView(header);
            adapter.addAdapter(arrayAdapter);
            adapter.addView(header2);
            adapter.addView(resultsView);
            adapter.addView(header3);
            adapter.addAdapter(arrayAdapter3);
            setListAdapter(adapter);

            Log.v("BGThread", "Filled Merge Adapter Team");

     } else {

         arrayAdapter = new ArrayAdapter<String>(this, R.layout.single_item, newsList);
            arrayAdapter2 = new ArrayAdapter<String>(this, R.layout.single_item, newsList2);
            //arrayAdapter3 = new ArrayAdapter(this, R.layout.complex_item, newsList3);

             String[] mStrings = (String[]) imageList.toArray(new String[imageList.size()]);
             String[] news = (String[]) newsList3.toArray(new String[newsList3.size()]);


             arrayAdapter3 = new LazyAdapter(this, mStrings, news);


                ListView list = getListView();
                   list.setTextFilterEnabled(true);

                   LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE );
                    View header3 = inflater.inflate( R.layout.homeheader3, list, false);


            //setListAdapter (arrayAdapter);


                adapter = new MergeAdapter();
                adapter.addView(header3);
                adapter.addAdapter(arrayAdapter3);
                setListAdapter(adapter);

                Log.v("BGThread", "Filled Merge Adapter League");
         } 
}

A quick and easy way is to add a boolean field to your class which is initially true: 一种快速简便的方法是将一个布尔字段添加到您的类中,这最初是正确的:

private boolean bothFeedsLoaded = true;

Then toggle it's value in onPostExecute: 然后在onPostExecute中切换它的值:

bothFeedsLoaded = !bothFieldsLoaded;

In your FillData method: 在您的FillData方法中:

if (!bothFeedsLoaded){return;}

As bothFeedsLoaded is initially true, then the first callback to onPostExecute (after whichever feed loads first) will change it to false. 由于bothFeedsLoaded最初为true,因此onPostExecute的第一个回调(无论哪个feed首先加载)都将其更改为false。 Your fillData method will therefore return without doing anything. 因此,您的fillData方法将不执行任何操作而返回。 When the second feed finished loading, onPostEexcute will change it back to true and your fillData will do it's thing. 当第二个提要完成加载时,onPostEexcute会将其更改回true,然后fillData会执行此操作。

Alternatively (and perhaps a little easier to read in 6 months time) is to use an integer: 或者(使用6个月的时间可能更容易阅读)是使用整数:

private int feedsLoaded = 0;

.....

feedsLoaded ++;

.....

if (feedsLoaded != 2) {return;}

There are better ways, eg creating separate classes for each loading task then synchronising both with a semaphore in their respective onPostExecute callbacks, but this should work. 有更好的方法,例如,为每个加载任务创建单独的类,然后在各自的onPostExecute回调中将两者与信号量同步,但这应该可以工作。

If using AsyncTask is not crucial, i would suggest the use of Thread class along with Handler, 如果使用AsyncTask不是很关键,我建议与Handler一起使用Thread类,

  1. You can use join , the class which has those two methods, let it implement Runnable interface, then you can make an object of the class and pass it to the Thread constructor. 您可以使用具有这两种方法的类join ,让它implement Runnable接口,然后可以创建该类的对象并将其传递给Thread构造函数。 Then use join on the thread, that means until and unless the thread dies it wont execute the below line, and just after the join, use the lines to place the data on the UI. 然后在线程上使用join,这意味着直到线程线程死掉为止,除非线程死亡,否则将不执行以下行,并且在连接之后,使用这些行将数据放置在UI上。

  2. You can also you CountDownLatch from java.util.Concurrent package, which will wait for the specific work to be done, and then execute further. 您也可以从java.util.Concurrent包中进行CountDownLatch ,它将等待特定的工作完成,然后进一步执行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 确保已在Android上加载嵌入式字体资源 - Make sure embedded font asset has loaded on Android 以下代码中正确使用了asynctask吗? - Has asynctask been used correctly in the code below? AsyncTask android异常(无法执行任务:该任务已经执行) - AsyncTask android exception (Cannot execute task: the task has already been executed) 执行后如何取消AsyncTask? - How to cancel an AsyncTask after it has been executed? Java:尚未加载屏幕 - Java: Screen has not been loaded 如何确保文件已成功写入? - How to be sure a file has been successfully written? 如何随机组合2个数组的元素,同时确保在所有元素至少使用一次之前不要重用元素? - How to randomly combine elements of 2 arrays while making sure to not reuse an element until all have been used at least once? 如何确保每次调用片段时都不会重新检索从服务器检索到的数据 - How to make sure that data that has been retrieved from a server is not re-retrieved every time a fragment is called 确保数组中的所有元素都不为零 - Making sure that all elements in array is not zero 即使已加载我的文件(Android Studio,libGDX,Java),AssetManager.get()也返回null - AssetManager.get() returns null even if my file has been loaded (Android Studio, libGDX, Java)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM