即使我在线程中更新它,为什么filteredList是空的?
问题描述:
我在后台线程中执行机器人后台操作,如下所示:作为线程由于码附加配置文件来过滤列表(filteredList.add(profile
)运行即使我在线程中更新它,为什么filteredList是空的?
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
应该被修改。
在此switch语句之外,我返回filteredList,理论上该语句应该是非空的,因为if
语句正在运行(条件符合),但filteredList是空的。
D/BirthdayFilter: [] END RESULT
D/BirthdayFilter: [{"birthday":"02-08-2016","favouriteIds":["62InvCZG9jaEmUNiJsssTIjImqY2"],"firstName":"Edal","friendIds":["62InvCZG9jaEmUNiJsssTIjImqY2"],"lastName":"Grunt","userId":"62InvCZG9jaEmUNiJsssTIjImqY2"}]IN THREAD
即使我在线程中更新它,为什么filteredList为空?
答
这是您遇到的一个经典并发问题。 Runnable
的run
方法中的代码与主代码并行执行(与Runnable
s和Thread
s的整体目的相同)并独立执行。因此,Java Runtime不保证执行顺序!有时你的if语句将在返回语句之前被评估,大多数情况下,尽管它是相反的。
你可能想要做的是通知你的主线程在你的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);
您可能需要考虑将列表传递给您的接口和方法,以便您可以直接使用新数据更新列表。
或者,如果它是一个耗时的后台操作,你可能要考虑使用AsyncTask
它有一个onPostExecute
方法,使得它易于使用。
所以我应该使用一个接口? @ TR4Android –
由于它是一个内部类,您应该可以直接调用外部类的方法(例如'Activity')。你在使用哪个课程? – TR4Android
我从一个叫做Filter的类运行这个类,像这样从一个片段调用:new BirthdayFilter(this)。过滤器(mAllProfiles,位置) –