【问题标题】:How to get contents of arraylist from first activity in second activity如何从第二个活动中的第一个活动获取arraylist的内容
【发布时间】:2017-08-07 13:33:15
【问题描述】:

所有Task.java

public class AllTask extends AppCompatActivity{


    ArrayList<Company> companyList;
    Bundle extras;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.task_list);


        companyList=new ArrayList<>();
        companyList.add(new Company("Kony Labs","10:30","Good"));
        companyList.add(new Company("Delloite","12:30","Very Good"));
        companyList.add(new Company("Accenture","14:30","Average"));
        companyList.add(new Company("Microsoft","16:30","Very Good"));
        companyList.add(new Company("TCS","18:30","Good"));


    }
}

AllReports.java

public class AllReports extends AppCompatActivity {

    ArrayList<Company> report_companyList;
    Bundle extras;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_all_reports);


        getSupportActionBar().setTitle("Reports");

        AllTask all_tasks=new AllTask();
        report_companyList=new ArrayList<>(all_tasks.companyList);



        ListView listView = (ListView) findViewById(R.id.report_list);

        MyAdapterResults myAdapter=new MyAdapterResults(this,R.layout.list_view_row_item,report_companyList);
        listView.setAdapter(myAdapter);
    }
}

我想在第二个活动的ListView 的第一个活动中显示 ArrayList 中的数据,但是当我试图从第二个活动的第一个活动中获取数据时,它给 NullPointerException 的 ArrayList 是空的。第二个activity如何获取ArrayList的内容。

【问题讨论】:

    标签: android android-activity arraylist


    【解决方案1】:

    你可以让你的companyList静态

    static ArrayList<Company> companyList;
    

    然后这样称呼它:

    AllTask.companyList
    

    不推荐这种方法。您应该在 Company 类中实现 SerializableParcelable 并像这样传递数据:

    Bundle bundle = new Bundle();
    bundle.putSerializable("data", companyList);
    intent.putExtras(bundle);
    

    并像这样从第二个活动中读取它:

    Bundle bundle = getIntent.getExtras();
    List<Company> data= (List<Company>)bundle.getSerializable("data");
    

    【讨论】:

    • 虽然此解决方案有效,但如果数据集变得太大,与Parcelable 解决方案相比,可序列化将非常慢。
    • 在编辑中添加了Parcelable,实际上它比任何其他解决方案都好,但我没有一个很好的做法,它也“可序列化”它对于android开发的新手来说很简单
    • 我同意,并且我已经对答案投了赞成票。我只是认为让新开发者知道这个问题还有其他解决方案是件好事。
    【解决方案2】:

    首先,将您的 Company 对象设为可序列化

    public class Company implements Serializable {
      //Your code
    }
    

    从 AllTask​​ Activity 你应该像这样打开 AllReports,

    Intent intent = new Intent(this, AllReports.class);
    
    intent.putExtra("companyList", companyList);
    
    startActivity(intent);
    

    你可以像这样进入AllReports,

    ArrayList<Company> companyList = (ArrayList<Company>)getIntent().getSerializableExtra("companyList");
    

    【讨论】:

    • 在 Android 上使用 Serializable 被认为是不好的做法,请改用 Parcelable
    【解决方案3】:

    您应该通过意图发送它。

    首先让你的 Company bean 实现 Serializable

    然后在你的 firstActivity 中这样做:

     Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
     intent.putExtra("array",companyList);
     startActivity(intent);
    

    然后在 onCreate 中的 SecondActitvity 中这样做:

     ArrayList<Company> companyList = (ArrayList<Company>) getIntent().getSerializableExtra("array");
    

    【讨论】:

      【解决方案4】:

      您可以将 Parcelable 数组传递给您的活动。至少对于 Android,它比 Serializable 更有效。但是您的公司应该为此实施Parcelable

       @Override
          protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
      
              Intent i = new Intent(this, SecondActivity.class);
      
              ArrayList<Company> companies = new ArrayList<>();
              //fill companies
      
              i.putParcelableArrayListExtra("EXTRA", companies);
              startActivity(i);
          }
      
          public class SecondActivity extends Activity {
              @Override
              protected void onCreate(Bundle savedInstanceState) {
                  super.onCreate(savedInstanceState);
                  setContentView(R.layout.activity_main);
      
                  ArrayList<Company> companies = getIntent().getParcelableArrayListExtra("EXTRA");
              }
          }
      

      【讨论】:

        【解决方案5】:

        使用 Application 类来做到这一点的好方法,它允许您在各种 Activity、Fragment 或 Dialog 中使用相同的对象。

        只创建一个对象,并且可以多次使用 从应用程序的任何地方访问 我正在添加我使用过的示例代码:

        public class Application extends Application {
        ArrayList<Filepath> arrayFilePath;
        
            @Override
            public void onCreate() {
                super.onCreate();
                this.sharedPreferences = getSharedPreferences(Constant.Userdata.USER_PREF.name(), Context.MODE_PRIVATE);
            }
        public ArrayList<Filepath> getArrayListForImagePath() {
                String fileurl = sharedPreferences.getString(Constant.Userdata.ARRAYLISTFILEPATH.name(), "");
                Gson gson = new Gson();
                if (fileurl.isEmpty()) {
                    arrayFilePath = new ArrayList<Filepath>();
                } else {
                    Type type = new TypeToken<ArrayList<Filepath>>() {
                    }.getType();
                    arrayFilePath = gson.fromJson(fileurl, type);
                }
                return arrayFilePath;
            }
        
            public void setArrayListForImagePath(ArrayList<Filepath> imagePath) {
                SharedPreferences.Editor editor = sharedPreferences.edit();
                Gson gson = new Gson();
        
                String jsonFilepath = gson.toJson(imagePath);
        
                editor.putString(Constant.Userdata.ARRAYLISTFILEPATH.name(), jsonFilepath);
                editor.commit();
            }
        
            public void clearArrayListForImagePath() {
                SharedPreferences.Editor editor = sharedPreferences.edit();
                editor.remove(Constant.Userdata.ARRAYLISTFILEPATH.name()).commit();
            }
        

        常量类:

        public class Constant {
        
            enum Userdata {
                USER_PREF, USER_ID, ARRAYLISTFILEPATH
            }
        }
        

        【讨论】:

          【解决方案6】:

          我将使用非本地解决方案来回答。

          您也可以使用 Green Robot 的 EventBus 来实现您想要的,而无需使用 SerializableParcelable 的样板文件。当您处理大型数据集或许多 Activity 调用时,其优势在于比两者都快得多。如果您的 pojo/bean/class 有很多字段,它还具有不必编写太多样板代码的优点。

          首先,添加对build.gradle 的依赖。

          compile 'org.greenrobot:eventbus:3.0.0'
          

          然后,定义一个 Event 类,负责将您的数据传输到应用程序中。请注意,这可能是从一个Activity 到另一个。从Fragment 到另一个。 Service 回到 Activity,以此类推。

          MessageEvent.java

          public class MessageEvent { 
              public ArrayList<Company> mCompanyList;
              // Add additional fields here if needed
          
              public MessageEvent(ArrayList<Company> list) {
                  this.mCompanyList = list;
              }
          }
          

          现在,您可以定义订阅者,也可以发布stickyEvent 并在ActivityB 上获取。就像下面的两个例子一样。

          选项 1:定义订阅者

          ActivityB.java

          public class ActivityB extends AppCompatActivity {
              // ...
          
               @Override
               public void onStart() {
                   super.onStart();
                   EventBus.getDefault().register(this);
               }
          
               @Override
               public void onStop() {
                   super.onStop();
                   EventBus.getDefault().unregister(this);
               }
          
              @Subscribe(sticky = true, threadMode = ThreadMode.MAIN)  
              public void onMessageEvent(MessageEvent event) {
                  EventBus.getDefault().removeStickyEvent(event);
                  ArrayList<Company> list = event.mCompanyList;
                  // Do whatever you want to do with the data.
              };
          }
          

          ActivityA.java

          public class ActivityA extends AppCompatActivity {
          
              // ...
          
              private void startActB(ArrayList<Company> list) {
                  Intent it = new Intent(ActivityA.this, ActivityB.class);
          
                  EventBus.getDefault().postSticky(new MessageEvent(list));
          
                  startActivity(it);
              }
          }
          

          选项 2:在 ActivityB 上获得粘性事件而不订阅

          ActivityA.java

          只需像上面的示例一样发布MessageEvent 并启动ActivityB

          ActivityB.java

          public class ActivityB extends AppCompatActivity {
          
              private ArrayList<Company> mCompanyList;
          
              @Override
              protected void onCreate(Bundle savedInstanceState) {
                  super.onCreate(savedInstanceState);
                  setContentView(R.layout.activity_b);
          
                  // Other stuff you might want to do here.
          
                  // Get the event that was posted on Activity A.
                  MessageEvent event = EventBus.getDefault().removeStickyEvent(MessageEvent.class);
          
                  // Check if it exists.
                  if (event != null) {
                      mCompanyList = event.mCompanyList;
                      // Do whatever you want with it.
                  }
                  else {
                      // Do something if the event wasn't posted prior to this Activity call.
                  }
              }
          
              // ...
          }
          

          您可以参考this link 来检查EventBus 与SerializableParcelable 相比的运行速度。

          更多详情,您可以查看project page,或this tutorial

          【讨论】:

            猜你喜欢
            • 2020-05-05
            • 2016-03-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-04-18
            • 2023-04-02
            相关资源
            最近更新 更多