收到广播后更新ListView

时间:2015-10-01 11:16:21

标签: android listview

我正在开发一款通过obd2端口轮询车辆传感器的应用程序。一切都很顺利,现在我正在添加一项新活动,显示哪些传感器得到支持,哪些传感器不受支持。

现在的问题是,用户可能会在检查完所有支持的命令之前启动活动,因此当变量发生变化时,需要更新ListView。

现在所有可用的pid都存储在主视图上的变量中,但一旦更改,它就会在支持视图上进行广播和更新。

我遇到的问题是它不想自动更新列表视图。我已经通过SF的多个线程,到目前为止尚未找到解决方案。我已经尝试了从创建自定义处理程序和接收器到在UI线程上运行它的所有内容。

这是完整的活动:

public class SupportedView extends ListActivity {
ArrayAdapter<Spanned> mAdapter;
ArrayList<Spanned> commandsList;
private String availpids;

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context context, Intent intent) {
        // Get extra data included in the Intent
        PowerManager powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        PowerManager.WakeLock wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                "ObdReader");

        if (!wakeLock.isHeld()){
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            wakeLock.acquire();
        }

        String pids32 = intent.getParcelableExtra("pids");

        updateList(pids32);
        Log.d("receiver", "Got message: Updated PIDS" );


        mAdapter.notifyDataSetChanged();

        Toast.makeText(context, "Received and tried update", Toast.LENGTH_LONG).show();

    }
};

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.sl_listview);
    //Set fullscreen
    availpids = MainView.pids32_val;
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

    LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
            new IntentFilter("pids"));

    updateList(availpids);

    mAdapter = new ArrayAdapter<Spanned>(this, R.layout.sllist_item, commandsList);
    setListAdapter(mAdapter);
    //ListView lv = getListView();

}


public void updateList(String listPids){
    commandsList = new ArrayList<>();
    final ArrayList<Spanned> tmpEnabled = new ArrayList<>();
    final ArrayList<Spanned> tmpDisabled = new ArrayList<>();

    for (ObdCommand Command : ObdConfig.getCommands()) {
        int commandKey = Command.getKey();

        if(commandKey > 0 && commandKey < 999 && listPids != null) {
            boolean isSupported = String.valueOf(listPids.charAt(commandKey - 1)).equals("1");
            if (isSupported) {
                tmpEnabled.add(Html.fromHtml( "<font color=\"green\">"  + Command.getName() + " isn't supported</font>"));
            }else {
                tmpDisabled.add(Html.fromHtml("<font color=\"red\">" + Command.getName() + " is supported</font>"));
            }
        }
    }
    commandsList.addAll(tmpEnabled);
    commandsList.addAll(tmpDisabled);
}


@Override
protected void onDestroy() {
    // Unregister since the activity is about to be closed.
    super.onDestroy();
}


}

1 个答案:

答案 0 :(得分:0)

让我们来看看你的更新列表()&#39;方法:

它使用带有pids的String并创建并填充

  

new ArrayList()

命名&#39; commandsList&#39;。

实际上,您对两个不同的对象使用相同的名称。另一个对象是您声明为类变量(成员)的ArrayList<Spanned>,并被指定为您的&#39; onCreate()&#39;中ListView的数据源。方法

我认为您在方法中的意图&#39; updateList()&#39;是清空数据源列表,然后用pids填充它。

要实现这一点,请按如下方式更改方法:

public void updateList(String listPids)
{
    // empty the data source list:
    commandsList.clear();

    final ArrayList<Spanned> tmpEnabled = new ArrayList<>();
    final ArrayList<Spanned> tmpDisabled = new ArrayList<>();

    for (ObdCommand Command : ObdConfig.getCommands()) 
    {
       // keep this part as before ...
    }

    commandsList.addAll(tmpEnabled);
    commandsList.addAll(tmpDisabled);
    // now, you have indeed changed the data set :) 
}

除此之外,为了确保BroadcastReceiver在需要时可用,您应该在&#39; onResume()&#39;并在&#39; onPause()&#39;中取消注册(方法&#39; onDestroy()&#39;不保证被调用。)