为什么filterList为空,即使我在线程中更新它?

时间:2016-08-14 09:27:29

标签: android multithreading

我在android中的后台线程中执行后台操作,如下所示:

switch (position) {   

    final List<Profile> filteredList = new ArrayList<>(0);
    case BELATED:
            Runnable belatedRunnable = new Runnable() {
                @Override
                public void run() {
                    for (Profile profile : allBirthdayProfiles) {
                        String birthday = profile.getBirthday();

                        String[] values = birthday.split("-");
                        int day = Integer.parseInt(values[0]);
                        int month = Integer.parseInt(values[1]);

                        SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
                        Calendar calendar = Calendar.getInstance();
                        String currentDate = formatter.format(calendar.getTime());
                        String[] currentDateValues = currentDate.split("-");
                        int currentDay = Integer.parseInt(currentDateValues[0]);
                        int currentMonth = Integer.parseInt(currentDateValues[1]);

                        if (month < currentMonth)
                            filteredList.add(profile);
                        else if (month == currentMonth && day < currentDay)
                            filteredList.add(profile);
                            Log.d(TAG, filteredList + "   IN THREAD");
                    }
                }
            };
            Thread belatedThread = new Thread(belatedRunnable);
            belatedThread.setName("FilterBelatedThread");
            belatedThread.start();
            break;

        default:
            return allBirthdayProfiles;
    }
    Log.d(TAG, filteredList + "    END RESULT");
    return filteredList;
}

由于代码将配置文件附加到已过滤列表(List<Profile> filteredList),因此应该在线程运行时修改filteredList.add(profile

在这个switch语句之外我返回filteredList,理论上它应该是非null,因为运行了if语句(满足条件),但是filteredList是空的。

D/BirthdayFilter: []    END RESULT
D/BirthdayFilter: [{"birthday":"02-08-2016","favouriteIds":["62InvCZG9jaEmUNiJsssTIjImqY2"],"firstName":"Edal","friendIds":["62InvCZG9jaEmUNiJsssTIjImqY2"],"lastName":"Grunt","userId":"62InvCZG9jaEmUNiJsssTIjImqY2"}]IN THREAD

为什么filterList为空,即使我在线程中更新它?

1 个答案:

答案 0 :(得分:4)

这是您在此遇到的经典并发问题。 run Runnable方法中的代码与主代码并行执行(这是RunnableThread s的全部目的)。因此,Java Runtime无法保证执行顺序!有时你的if语句将在return语句之前进行评估,大部分时间都是相反的。

您可能想要做的是通知主线程您在run方法中所做的更改。根据您的设置,这可能与此类似:

Runnable belatedRunnable = new Runnable() {
    @Override
    public void run() {
        // ... normal code here
        updateList(); // notify main thread of changes
    }
}

然后为您的活动添加一个新方法,根据需要更新列表:

private void updateList() {
    // update your list
}

或者,如果您将此作为独立组件使用,则需要将侦听器传递给该方法,以便它可以通知调用方更改。例如,创建一个新界面:

public interface Updateable {
    void update();
}

然后在您的调用类中实现此接口,例如:

public MyFragment extends Fragment implements Updateable {
    // ...
    @Override
    public void update() {
        // update your list here
    }
}

然后将其添加到您的方法中:

public void filter(/* ... */ final Updateable listener) {
    // inside your run method:
    listener.update();
}

最后在你的调用类中调用你的方法,如下所示:

filter(/* ... */ this);

您可能需要考虑将列表传递给update接口和方法,以便直接使用新数据更新列表。

或者,如果这是一项耗时的后台操作,您可能需要考虑使用AsyncTask,其onPostExecute方法使其易于使用。