java - Android 可分块对象在 Activity 之间克隆

标签 java android object synchronization parcelable

我有一个类,它实现了 Parcelable 接口(interface)以及所有必需的读写方法。 这些是我的可分割对象的重要方法......

...

public News() {
    // Default constructor...
}

@SuppressWarnings("unchecked")
private News(Parcel in) {
    this.feedId = in.readLong();
    this.ownerId = in.readLong();
    this.author = in.readParcelable(User.class.getClassLoader());
    this.ownerUserName = in.readString();
    this.title = in.readString();
    this.content = in.readString();
    this.image = in.readParcelable(NewsImage.class.getClassLoader());
    this.videoUrl = in.readString();
    this.date = in.readString();
    this.tags = in.readArrayList(Hashtag.class.getClassLoader());
    this.ownerNewspaperName = in.readString();
    this.view = in.readString();
    this.applaud = in.readString();
    this.comment = in.readString();
    this.announce = in.readString();
    this.isApplauded = in.readByte() == 1;
    this.isCommented = in.readByte() == 1;
    this.isAnnounced = in.readByte() == 1;
    this.isViewed = in.readByte() == 1;
    this.isHidden = in.readByte() == 1;
    this.isReported = in.readByte() == 1;
}

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

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeLong(this.feedId);
    dest.writeLong(this.ownerId);
    dest.writeParcelable(this.author, flags);
    dest.writeString(this.ownerUserName);
    dest.writeString(this.title);
    dest.writeString(this.content);
    dest.writeParcelable(this.image, flags);
    dest.writeString(this.videoUrl);
    dest.writeString(this.date);
    dest.writeList(this.tags);
    dest.writeString(this.ownerNewspaperName);
    dest.writeString(this.view);
    dest.writeString(this.applaud);
    dest.writeString(this.comment);
    dest.writeString(this.announce);
    dest.writeByte((byte) (this.isApplauded ? 1 : 0));
    dest.writeByte((byte) (this.isCommented ? 1 : 0));
    dest.writeByte((byte) (this.isAnnounced ? 1 : 0));
    dest.writeByte((byte) (this.isViewed ? 1 : 0));
    dest.writeByte((byte) (this.isHidden ? 1 : 0));
    dest.writeByte((byte) (this.isReported ? 1 : 0));
}

public static final Creator<News> CREATOR = new Creator<News>() {
    @Override
    public News createFromParcel(Parcel source) {
        return new News(source);
    }

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

...

我的 Activity 包含带有数组适配器的 ListView ,其中包含我的可包裹对象的数组列表。单击列表项时,我将特定的 Parcelable 对象传递给 DetailActivity,并且我可以毫无问题地读取 Parcelable 对象......直到现在一切都很完美...... 大问题从这里开始...... 当我更改此对象的任何属性(写入)时,我实际上只是更改克隆而不是先前 Activity ListView 中保存的原始对象。 我认为出现这个问题的原因是,Parcelable.Creator 从 Parcel 返回一个新对象,而不是 God 对象引用。

只是克隆...

My NewsDetailActivity.class 我向此 Activity 中的对象写入新值...

public class NewsDetailActivity extends Activity {

//private static final String TAG = "NewsDetailActivity";

public static final String KEY_NEWS = "news";

public static final String KEY_IS_WILLING_TO_COMMENT = "is_willing_to_comment";

private News news;

private float containerWidth;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_news_detail);

    final ActionBarBuilder builder = new ActionBarBuilder(getActionBar());
    builder.initializeSupportiveProperties();

    final String screenName = getResources().getString(R.string.android) + "/" + getTitle();

    final Tracker tracker = ((PapiroomApplication)getApplication()).getTracker(TrackerName.APP_TRACKER);
    tracker.setScreenName(screenName);
    tracker.send(new HitBuilders.AppViewBuilder().build());

    news = getIntent().getParcelableExtra(KEY_NEWS);

    final boolean isWillingToComment = getIntent().getBooleanExtra(KEY_IS_WILLING_TO_COMMENT, false);

    containerWidth = this.getResources().getDisplayMetrics().widthPixels - 20;

    // Layout initialization
    final ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView1);
    final RoundedImageView imgNewsUser = (RoundedImageView) findViewById(R.id.imgNewsDetailUser);
    final PapiroomTextView txtViewCount = (PapiroomTextView) findViewById(R.id.txtNewsView);
    final PapiroomTextView txtNewspaperName = (PapiroomTextView) findViewById(R.id.txtNewsDetailNewspaperName);
    final PapiroomTextView txtNewsUsername = (PapiroomTextView) findViewById(R.id.txtNewsDetailUsername);
    final PapiroomTextView txtNewsDate = (PapiroomTextView) findViewById(R.id.txtNewsDetailDate);
    final PapiroomTextView txtNewsTitle = (PapiroomTextView) findViewById(R.id.txtNewsDetailTitle);
    final ImageView imgNews = (ImageView) findViewById(R.id.imgNewsDetail);
    final ImageView imgNewsVideo = (ImageView) findViewById(R.id.imgNewsDetailVideo);
    final PapiroomTextView txtNewsContent = (PapiroomTextView) findViewById(R.id.txtNewsDetailContent);
    final PapiroomTextView txtNewsApplaudCount = (PapiroomTextView) findViewById(R.id.txtNewsDetailApplaudCount);
    final PapiroomTextView txtNewsCommentCount = (PapiroomTextView) findViewById(R.id.txtNewsDetailCommentCount);
    final PapiroomTextView txtNewsAnnounceCount = (PapiroomTextView) findViewById(R.id.txtNewsDetailAnnounceCount);
    final FrameLayout containerApplaud = (FrameLayout) findViewById(R.id.layoutApplaud);
    final FrameLayout containerAnnounce = (FrameLayout) findViewById(R.id.layoutAnnounce);
    final FrameLayout containerMore = (FrameLayout) findViewById(R.id.layoutMore);
    final ImageView imgNewsMore = (ImageView) findViewById(R.id.imgMore);
    final ImageView btnNewsDetailComment = (ImageView) findViewById(R.id.btnNewsDetailComment);
    final LinearListView listComment = (LinearListView) findViewById(R.id.listNewsDetailComment);
    final PapiroomAutoCompleteTextView txtNewsDetailComment = (PapiroomAutoCompleteTextView) findViewById(R.id.txtNewsDetailComment);

    final NewsImage image = news != null ? news.getImage() : null;
    final float height = image != null ? calculate(image.getWidth(), image.getHeight()) : 0f;
    if(height >= 2000) imgNews.setScaleType(ScaleType.CENTER_CROP);
    imgNews.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, (int) height));
    imgNews.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            onImageClicked(news);
        }
    });

    if(news.isVideo()) {
        imgNewsVideo.setVisibility(View.VISIBLE);
        imgNewsVideo.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                onImageClicked(news);
            }
        });
    }

    txtNewsContent.setMovementMethod(new PapiroomMovementMethod());

    txtNewsApplaudCount.setText(news.getApplaudCount());
    txtNewsApplaudCount.setOnClickListener(new ApplaudCounterClickListener(this, news));

    txtNewsCommentCount.setText(news.getCommentCount());

    txtNewsAnnounceCount.setText(news.getAnnounceCount());
    txtNewsAnnounceCount.setOnClickListener(new AnnounceCounterClickListener(this, news));

    // Applaud View Imp.
    containerApplaud.setVisibility(news.isHidden() ? View.GONE : View.VISIBLE);
    containerApplaud.setBackgroundResource(news.isApplauded() ? R.drawable.bg_circular_active : R.drawable.bg_circular_passive);
    containerApplaud.setOnTouchListener(new PapiroomButtonOnTouchListener(containerApplaud, new ApplaudButtonClickListener(this, news, containerApplaud, txtNewsApplaudCount, true)));

    // Announce View Imp.
    containerAnnounce.setVisibility(news.isHidden() || news.getAuthor().getUserId() == MainActivity.getUser().getUserId() ? View.GONE : View.VISIBLE);
    containerAnnounce.setBackgroundResource(news.isAnnounced() ? R.drawable.bg_circular_active : R.drawable.bg_circular_passive);
    containerAnnounce.setOnTouchListener(new PapiroomButtonOnTouchListener(containerAnnounce, new AnnounceButtonClickListener(this, news, containerAnnounce, txtNewsAnnounceCount)));

    imgNewsMore.setImageResource(R.drawable.ic_more);
    containerMore.setOnTouchListener(new PapiroomButtonOnTouchListener(containerMore, new MoreButtonClickListener(this, news)));

    //final MentionAdapter adapter = new MentionAdapter(this, new ArrayList<User>());
    //adapter.setNotifyOnChange(true);

    // If comment btn was triggered from previous activity
    if(isWillingToComment) txtNewsDetailComment.requestFocus();

    imgNewsUser.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            goToUserPage(news);
        }
    });

    final MentionTextWatcher watcher = new MentionTextWatcher(null, btnNewsDetailComment);
    txtNewsDetailComment.addTextChangedListener(watcher);

    if(!news.isViewed()) new IncreaseViewCountTask(this, news).execute();

    // Initialization
    final CommentAdapter commentAdapter = new CommentAdapter(this, news.getAuthor().getUserId(), txtNewsDetailComment, news, listComment);
    listComment.setDividerDrawable(null);
    listComment.setAdapter(commentAdapter);

    btnNewsDetailComment.setOnClickListener(new PostCommentButtonClickListener(this, commentAdapter, txtNewsDetailComment, news.getFeedId(), scrollView));

    new GetLastCommentsTask(this, listComment, commentAdapter, news).execute();

    if(news != null) {
        final User author = news.getAuthor();
        PapiroomApplication.getImageLoader().displayImage(author.getProfileImageUrl(), imgNewsUser, PapiroomApplication.getOptionsUser());
        txtViewCount.setText(news.getViewCount());
        txtNewspaperName.setText(author.getNewspaperName() != null ? author.getNewspaperName() : news.getOwnerNewspaperName());
        txtNewsUsername.setText(author.getUsername() != null ? "@" + author.getUsername() : "@" + news.getOwnerUserName());
        txtNewsDate.setText(DateTimeUtils.getFormattedDateString(news.getDate()));
        txtNewsTitle.setText(news.getTitle());
        PapiroomApplication.getImageLoader().displayImage(news.getImage().getURL(), imgNews, PapiroomApplication.getOptionsNews());
        txtNewsContent.setText(Html.fromHtml(news.getContent()));
    }
}

private void onImageClicked(News news) {
    final String videoUrl = news.getVideoUrl();
    final String imageUrl = news.getImage().getURL();
    Intent intent;
    if(news.isVideo()) {
        intent = new Intent(this, WebViewActivity.class);
        intent.putExtra(WebViewActivity.KEY_URL, videoUrl);
    }
    else {
        intent = new Intent(this, FullScreenPhotoActivity.class);
        intent.putExtra(FullScreenPhotoActivity.KEY_URL, imageUrl);
    }
    this.startActivity(intent);
    this.overridePendingTransition(R.anim.activity_open_translate, R.anim.activity_close_scale);
}

private float calculate(int w, int h) {
    if(h > 0) {
        final float scale = (float) h / (float) w;
        final float calculated = (scale > 0f) ? (containerWidth * scale) : 0;
        return (calculated > 2000) ? 2000 : calculated;
    }
    else return 0;
}

private void goToUserPage(News news) {
    // Go To User Page
    final long userId = news.getAuthor().getUserId();
    if(userId != ProfileActivity.userId) {
        final String newspaperName = news.getAuthor().getNewspaperName();
        final Intent intent = new Intent(this, ProfileActivity.class);
        intent.putExtra(ProfileActivity.KEY_UID, userId);
        intent.putExtra(ProfileActivity.KEY_NEWSPAPER_NAME, newspaperName);
        startActivity(intent);
        overridePendingTransition(R.anim.activity_open_translate, R.anim.activity_close_scale);
    }
}

@Override
public void onResume() {
    super.onResume();
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    final int id = item.getItemId();
    switch (id) {
        case android.R.id.home:
            finish();
            break;
    }
    return super.onOptionsItemSelected(item);
}

@Override
public void finish() {
    super.finish();
    overridePendingTransition(R.anim.activity_open_scale, R.anim.activity_close_translate);
}
}

如何解决这个问题?

抱歉我的英语:)

最佳答案

我更喜欢使用广播接收器

关于java - Android 可分块对象在 Activity 之间克隆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28972552/

相关文章:

php - PHP中(对象)数组(键=>值)的反转是什么?

javascript - 如何根据对象名称创建 javascript 对象的实例

java - 字符串比较

java - 如何使用随机类在数组列表中找不到选择号?

java - 如何使用 Java native 访问 (JNA) 映射回调函数

Android google map turn by turn 导航

javascript - 使用map方法对数组进行分组

java - 如何使用 javamail 和 imap 永久删除邮件

java - 应用程序包中类的 NoClassDefFoundError

android - 当应用程序处于前台时,GCM 3.0 通知有效负载不显示 android 通知