即使我在线程中更新它,为什么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为空?

这是您遇到的一个经典并发问题。 Runnablerun方法中的代码与主代码并行执行(与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方法,使得它易于使用。

+0

所以我应该使用一个接口? @ TR4Android –

+0

由于它是一个内部类,您应该可以直接调用外部类的方法(例如'Activity')。你在使用哪个课程? – TR4Android

+0

我从一个叫做Filter的类运行这个类,像这样从一个片段调用:new BirthdayFilter(this)。过滤器(mAllProfiles,位置) –