Activity Fragmentデータ転送(対象)引用不変問題

15913 ワード

背景
一日コードを書いてbugを出しました.Activityがfragmentに伝えたarraylistがfragmentの中の修正を経てactivityのarrayListを変えました.その時は驚きました.長年のAndroidに対する認識を覆しました.
最初にこのブログを見つけました.http://www.cnblogs.com/duanxz/p/3566221.html  中ではbundleは伝達引用と言いますが、事実は違っています.次の例で証明します. ここは神様に感謝します.
転覆した常識
1.前列化逆序文化前後の対象の内容は同じですが、間違いなくオブジェクトではなく、同理ArayList(目測ActivityとFragmentの間には、序文逆序列化はありません)
2.直接ArayListを印刷するか、または対象を印刷すると、彼の住所が見えます(これはばかげていることを証明します!!!)
3.直接にオブジェクトを印刷したり、arraylistを印刷したり、またはhashcodeは印刷結果が同じであれば、それらの参照は必ず同じところを指します.(詳細はtoStringのソースコードを見ていますが、何年も間違えていました.恥ずかしいです.)
くりを一つください
1.MainActivityからSecondActivityへデータを転送する
MainActivity.java
package com.example.administrator.text0212;

import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    private ArrayList userList = new ArrayList<>();
    private ArrayList userListUseBundle = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        System.out.println("xcqw onCreate");
        setContentView(R.layout.activity_main);
        for(int i = 0;i<2;i++){
            User user = new User("  "+i+" ","man");
            userList.add(user);
        }

        for(int i= 0;i<3;i++){
            User user = new User("bundle"+i+" ","wonman");
            userListUseBundle.add(user);
        }
        findViewById(R.id.bt_jump).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                Bundle bundle = new Bundle();
                bundle.putParcelableArrayList("userListBundle",userListUseBundle);
                intent.putParcelableArrayListExtra("userList",userList);
                intent.putExtra("bundle",bundle);
                System.out.println("xcqw MainActivity userList   "+userList);
                System.out.println("xcqw MainActivity userList hashCode  "+userList.hashCode());
                System.out.println("xcqw MainActivity userListBundle   "+userListUseBundle);
                System.out.println("xcqw MainActivity userListBundle hashCode  "+userListUseBundle.hashCode());
                startActivity(intent.setClass(MainActivity.this,SecondActivity.class));
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        System.out.println("xcqw userList.size()"+userList.size());
        System.out.println("xcqw userListUseBundle.size()"+userListUseBundle.size());
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        System.out.println("xcqw onDestory");
    }
}
SecondActivity.java
package com.example.administrator.text0212;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;

import java.util.ArrayList;

public class SecondActivity extends AppCompatActivity {
    private ArrayList userList2 = new ArrayList<>();
    private ArrayList userListBundle2 = new ArrayList<>();
    public ArrayList userList;
    private ArrayList userListBundle;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
        Intent intent = getIntent();
        userList = intent.getParcelableArrayListExtra("userList");
        Bundle bundle = intent.getBundleExtra("bundle");
        userListBundle = bundle.getParcelableArrayList("userListBundle");
        System.out.println("xcqw SecondActivity userList   " + userList);
        System.out.println("xcqw SecondActivity userList hashCode  " + userList.hashCode());
        System.out.println("xcqw SecondActivity userListBundle   " + userListBundle);
        System.out.println("xcqw SecondActivity userListBundle hashCode  " + userListBundle.hashCode());

        userList2.addAll(userList);
        userListBundle2.addAll(userListBundle);

        System.out.println("xcqw SecondActivity userList2   " + userList);
        System.out.println("xcqw SecondActivity userList2 hashCode  " + userList.hashCode());
        System.out.println("xcqw SecondActivity userListBundle2   " + userListBundle);
        System.out.println("xcqw SecondActivity userListBundle2 hashCode  " + userListBundle.hashCode());

        if (userList2 == userList) {
            System.out.println("xcqw      1");
        } else {
            System.out.println("xcqw userList2 != userList");
            System.out.println("xcqw userList.getClass()" + userList.getClass());
            System.out.println("xcqw userList2.getClass()" + userList2.getClass());
            System.out.println("xcqw SecondActivity userList   " + userList);
            System.out.println("xcqw SecondActivity userList hashCode  " + userList.hashCode());
            System.out.println("xcqw SecondActivity userList2   " + userList);
            System.out.println("xcqw SecondActivity userList2 hashCode  " + userList.hashCode());
        }

        if (userListBundle2 == userListBundle) {
            System.out.println("xcqw     2");
        } else {
            System.out.println("xcqw userListBundle2 != userListBundle");
            System.out.println("xcqw SecondActivity userListBundle   " + userListBundle);
            System.out.println("xcqw SecondActivity userListBundle hashCode  " + userListBundle.hashCode());
            System.out.println("xcqw SecondActivity userListBundle2   " + userListBundle);
            System.out.println("xcqw SecondActivity userListBundle2 hashCode  " + userListBundle.hashCode());
        }

        if (userList.equals(userList2)) {
            System.out.println("xcqw userList.equals(userList2)");
        } else {
            System.out.println("xcqw userList equals(userList2)");
        }

        if (userListBundle.equals(userListBundle2)) {
            System.out.println("xcqw userListBundle.equals(userListBundle2)");
        } else {
            System.out.println("xcqw userListBundle equals(userListBundle2)");
        }

        findViewById(R.id.bt_add_fragment).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ContentFragment contentFragment = new ContentFragment();
                Bundle bundle2 = new Bundle();
                bundle2.putParcelableArrayList("userListActivity", userList);
                bundle2.putString("succ", "   ");
                contentFragment.setArguments(bundle2);
                FragmentManager fragmentManager = getSupportFragmentManager();
                FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
                fragmentTransaction.replace(R.id.fl_container, contentFragment);
                fragmentTransaction.commitAllowingStateLoss();
            }
        });

        findViewById(R.id.bt_get_userlist).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(SecondActivity.this, "userList"+userList.size(), Toast.LENGTH_SHORT).show();
            }
        });
    }

}
(1)User equalsとhashCodeを上書きしていません.
package com.example.administrator.drawlayout;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Created by Administrator on 2017/2/12 0012.
 */
public class User implements Parcelable{

    private String name;
    private String sex;

    protected User(Parcel in) {
        name = in.readString();
        sex = in.readString();
    }

    public static final Creator CREATOR = new Creator() {
        @Override
        public User createFromParcel(Parcel in) {
            return new User(in);
        }

        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public User() {
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeString(name);
        parcel.writeString(sex);
    }

//    @Override
//    public boolean equals(Object o) {
//        if (this == o) return true;
//        if (!(o instanceof User)) return false;
//
//        User user = (User) o;
//
//        if (name != null ? !name.equals(user.name) : user.name != null) return false;
//        return sex != null ? sex.equals(user.sex) : user.sex == null;
//
//    }
//
//    @Override
//    public int hashCode() {
//        int result = name != null ? name.hashCode() : 0;
//        result = 31 * result + (sex != null ? sex.hashCode() : 0);
//        return result;
//    }

}
印刷結果:前の「試し」とは違って見えます.もちろんUserList 2!userList
MainActivity userList  [comp.example.administrator.text [email protected] 0212.User@af45d49」MainActivity userList hashCode 186635194 MainActivity userListBunle  [comp.example.administrator.text [email protected] [email protected] 0212.User@6f0b87c」MainActivity userListBunle hashCode -766434790/Activityから転送されたデータSecondActivity userListを受信する  [comp.example.administrator.text [email protected] 0212.User@34dc76b」SecondActivity userList hashCode -839526990 SecondActivity userListBunle  [comp.example.administrator.text [email protected] [email protected] 0212.User@ab3ba86」SecondActivity userListudle hashCode -51512212/ActivityのnewからのuserList、userListBund le 2 SecondActivity userList 2  [comp.example.administrator.text [email protected] 0212.User@34dc76b」SecondActivity userList 2 hashCode -839526990 SecondActivity userListBund le 2  [comp.example.administrator.text [email protected] [email protected] 0212.User@ab3ba86」SecondActivity userListBund le 2 hashCode -51512212 userList 2!=userList userList.get Class()class java.util.ArayList userList.get Class()class java.util.ArayList SecondActivity userList  [comp.example.administrator.text [email protected] 0212.User@34dc76b」SecondActivity userList hashCode -839526990 SecondActivity userList 2  [comp.example.administrator.text [email protected] 0212.User@34dc76b」SecondActivity userList 2 hashCode -83952690 userListBundele 2!=userList Bundele SecondActivity userListBunle  [comp.example.administrator.text [email protected] [email protected] 0212.User@ab3ba86」SecondActivity userListudle hashCode -51512212 SecondActivity userListBund le 2  [comp.example.administrator.text [email protected] [email protected] 0212.User@ab3ba86」SecondActivity userListBund le 2 hashCode -51512212 userList.equals(userList 2)userListBund le.equals(userListBundele 2)
(2)equalsを書き換える
印刷は前と同じです.
(3)equalsとhashCodeを書き換える
MainActivity userList  [comp.example.administrator.text [email protected] 0212.User@1bfaa011」MainActivity userList hashCode 216183170 MainActivity userListBunle  [comp.example.administrator.text [email protected] [email protected] 0212.User@793957dd」MainActivity userListBunle hashCode 928096571 SecondActivity userList  [comp.example.administrator.text [email protected] 0212.User@1bfaa011」SecondActivity userList hashCode 216183170 SecondActivity userListBunle  [comp.example.administrator.text [email protected] [email protected] 0212.User@793957dd」SecondActivity userListudle hashCode 928096571 SecondActivity userList 2  [comp.example.administrator.text [email protected] 0212.User@1bfaa011」SecondActivity userList 2 hashCode 216183170 SecondActivity userListBund le 2  [comp.example.administrator.text [email protected] [email protected] 0212.User@793957dd」SecondActivity userListBund le 2 hashCode 928096571 userList 2!=userList userList.get Class()class java.util.ArayList userList.get Class()class java.util.ArayList SecondActivity userList  [comp.example.administrator.text [email protected] 0212.User@1bfaa011」SecondActivity userList hashCode 216183170 SecondActivity userList 2  [comp.example.administrator.text [email protected] 0212.User@1bfaa011」SecondActivity userList 2 hashCode 216183170 userListBundele 2!=userList Bundele SecondActivity userListBunle  [comp.example.administrator.text [email protected] [email protected] 0212.User@793957dd」SecondActivity userListudle hashCode 928096571 SecondActivity userListBund le 2  [comp.example.administrator.text [email protected] [email protected] 0212.User@793957dd」SecondActivity userListBund le 2 hashCode 928096571 userList.equals(userList 2)userListBund le.equals(userListBund 2)
これはもう一度メモリアドレスが同じかどうかを証明します.hashcodeとは何の関係もないです.直接印刷対象から得られた値と関係がありません.同じでも同じです.
最初の例を説明します.
1.hashcodeと直接印刷対象とメモリアドレス(つまり参照)は関係ありません.
2.Bunndle転送もデータを伝えるのではなく引用を伝えるのです!!!
2.ActivityデータをFragmentに転送する
(1)equalsとhashCodeを上書きしていません.
コンテントは成功しました.  [comp.example.administrator.text [email protected] 0212.User@34dc76b」contentFragment userryList hashcode -839526990 contentFragment userryList.toString[comp.example.administrator.text [email protected] 0212.User@34dc76b"((SecondActivity)get Activity().userList==userArayList content Frame others List   [comp.example.administrator.text [email protected] 0212.User@34dc76b」contentFragment others List hashcode   -839526990 contentFragment others List.toString   [comp.example.administrator.text [email protected] 0212.User@34dc76b」(SecondActivity)getActivity().userList!=other UserList userArayListSize 2 clear userArayList userArayListSize 0
また別のボタンをクリックしてActivityのuserListのsizeを取得しても0です.
othersUserListとuserArayListは直接印刷した値はhascodeの値と同じですが、ソフトがないです.彼らはまだです. 
また、Activityがfragmentにデータを伝えたのは引用であることを証明しました.
(2)equalsを上書きする
すべての結果は上と同じです.
(3)equalsとhashcodeを上書きする
印刷したhashcodeの値が変わっただけです.結果は変わりませんでした.
三.まとめ
1.hashCodeと直接印刷対象の値はメモリアドレスと何の関係もありません.
2.ActivityとFragmentデータ転送会は対象の引用を保持します.parcellableであれ、Serizableであれ(なぜですか?研究を待っています.)
3.対象参照が同じかどうかを判断します.現在発見されているものは一つしかありません. obj 1==obj 2