Làm cách nào để truyền dữ liệu giữa các Hoạt động trong ứng dụng Android?


1348

Tôi có một kịch bản trong đó, sau khi đăng nhập thông qua một trang đăng nhập, sẽ có một đăng xuất buttontrên mỗi trang activity.

Khi nhấp vào sign-out, tôi sẽ chuyển session idngười dùng đã đăng nhập để đăng xuất. Bất cứ ai có thể hướng dẫn tôi làm thế nào để session idcó sẵn cho tất cả activities?

Bất kỳ thay thế cho trường hợp này


14
tôi đã sử dụng sharedpreference nó cũng hữu ích để giữ dữ liệu đăng nhập trên tính năng mật khẩu của người gửi
shareef

Điều này làm việc cho tôi. stackoverflow.com/a/7325248/2125322 Cảm ơn Darshan Computing
matasoy


đối với những trường hợp như vậy, hãy thử tạo lớp commomUtils bằng phương pháp sharedprefereces ... điều này sẽ giữ mã sạch và dữ liệu liên quan tại một nơi. Và bạn sẽ dễ dàng có thể Xóa bộ dữ liệu cụ thể chỉ bằng một phương pháp xóa các prefrences cụ thể đó mà không cần xóa bất kỳ dữ liệu ứng dụng mặc định nào ...
Muahmmad Tayyib

Câu trả lời:


1265

Cách dễ nhất để làm điều này là chuyển id phiên cho hoạt động đăng xuất trong khi Intentbạn đang sử dụng để bắt đầu hoạt động:

Intent intent = new Intent(getBaseContext(), SignoutActivity.class);
intent.putExtra("EXTRA_SESSION_ID", sessionId);
startActivity(intent);

Truy cập ý định đó vào hoạt động tiếp theo:

String sessionId = getIntent().getStringExtra("EXTRA_SESSION_ID");

Các tài liệu cho ý định có nhiều thông tin hơn (xem phần có tiêu đề "Extras").


ok nếu tôi vượt qua id phiên để đăng xuất tính nhạy cảm khi đăng nhập thành công và nó sẽ hoạt động trên bất kỳ trang hoạt động nào để đăng xuất hoặc theo cách thủ công tôi sẽ phải gán giá trị cho mỗi hoạt động ??? sử dụng thủ tục trên ??
UMAR

5
Có, bạn phải cung cấp ID phiên cho mọi hoạt động mà bạn muốn cho phép người dùng đăng xuất. Ngoài ra, bạn có thể lưu trữ nó trong đối tượng Ứng dụng, nhưng sau đó bạn phải quản lý trạng thái của phiên (kiểm tra xem nó có hợp lệ không trước khi sử dụng, v.v.).
Erich Doulass

1
Xin lưu ý rằng tài liệu chỉ ra như sau: Thêm dữ liệu mở rộng vào mục đích. Tên phải bao gồm tiền tố gói, ví dụ: ứng dụng com.android.contacts sẽ sử dụng các tên như "com.android.contacts.Show ALL".
Serguei Fedorov

1
Và để đọc dữ liệu từ hoạt động khác sử dụngLong session_ids=getIntent().getExtras().getLong("EXTRA_SESSION_IDS");
Farid

1
Làm thế nào chúng ta có thể truyền dữ liệu bằng cách sử dụng setDatavà sự khác biệt giữa hai luận điểm này là gì? Cái nào tốt hơn?
Hosein Aqajani

1402

Trong Hoạt động hiện tại của bạn, tạo một cái mới Intent:

String value="Hello world";
Intent i = new Intent(CurrentActivity.this, NewActivity.class);    
i.putExtra("key",value);
startActivity(i);

Sau đó, trong Hoạt động mới, lấy các giá trị đó:

Bundle extras = getIntent().getExtras();
if (extras != null) {
    String value = extras.getString("key");
    //The key argument here must match that used in the other activity
}

Sử dụng kỹ thuật này để truyền các biến từ Hoạt động này sang Hoạt động khác.


58
Chỉ là một thông tin cho những người mù như tôi: nếu bạn đặt một số nguyên trong hoạt động hiện tại của mình, bạn phải lấy nó trong một số mới thông qua extras.getInt("new_variable_name"). Nếu bạn cố gắng tải nó qua getString()Android, hãy xem int đã được đưa ra và trả về null!
bish

4
Điều gì xảy ra nếu hoạt động đã chạy, có cần phải làm gì startActivity(i);không? Ý tôi là, tôi có thể thực hiện hoạt động A gọi hoạt động B và trả lại dữ liệu cho hoạt động A không? tôi có bối rối không
Francisco Corrales Morales


Tôi thích biến chuỗi. Bạn luôn có thể chuyển đổi một chuỗi thành số nguyên hoặc float sau.
dùng914425

140

Vượt qua bổ sung ý định là một cách tiếp cận tốt như Erich đã lưu ý.

Tuy nhiên, đối tượng Ứng dụng là một cách khác và đôi khi dễ dàng hơn khi xử lý cùng một trạng thái qua nhiều hoạt động (trái ngược với việc phải đưa / đặt nó ở mọi nơi) hoặc các đối tượng phức tạp hơn so với nguyên thủy và Chuỗi.

Bạn có thể mở rộng Ứng dụng, sau đó đặt / nhận bất cứ thứ gì bạn muốn ở đó và truy cập nó từ bất kỳ Hoạt động nào (trong cùng một ứng dụng) với getApplication () .

Ngoài ra, hãy nhớ rằng các phương pháp khác mà bạn có thể thấy, như thống kê, có thể có vấn đề vì chúng có thể dẫn đến rò rỉ bộ nhớ . Ứng dụng giúp giải quyết điều này quá.


8
+1 cho bài toán thống kê. có lẽ việc dọn dẹp có thể được giải quyết bằng cách kết hợp một singleton với lớp Ứng dụng phương thức onCreate / onTerminate.
Syd

10
Hey, tôi biết chủ đề này đã được một thời gian trở lại, nhưng liên kết được cung cấp bây giờ là một ngõ cụt. Có nơi nào tôi có thể tìm thấy ví dụ?
JuiCe

Làm thế nào để đạt được điều này bằng cách sử dụng Ứng dụng? @CharlieCollins
Banee Ishaque K

Đây là một ví dụ cập nhật về điều này ở đây, từ một cuốn sách rất cũ :) github.com/charlieCollins/android-in-practice/blob/master/ch07/ Lỗi
Charlie Collins

@JuiCe Bài đăng trên blog của Nhà phát triển Android về rò rỉ bộ nhớ không còn hợp lệ.
Edric

94

Lớp nguồn:

Intent myIntent = new Intent(this, NewActivity.class);
myIntent.putExtra("firstName", "Your First Name Here");
myIntent.putExtra("lastName", "Your Last Name Here");
startActivity(myIntent)

Lớp đích (lớp NewActivity):

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.view);

    Intent intent = getIntent();

    String fName = intent.getStringExtra("firstName");
    String lName = intent.getStringExtra("lastName");
}

3
Ý định bao giờ có thể là null? Chúng ta có nên kiểm tra xem nó không null không?
Micro


85

Bạn chỉ cần gửi thêm trong khi gọi ý định của bạn.

Như thế này:

Intent intent = new Intent(getApplicationContext(), SecondActivity.class);
intent.putExtra("Variable name", "Value you want to pass");
startActivity(intent);

Bây giờ trên OnCreatephương pháp của bạn, SecondActivitybạn có thể tìm nạp các tính năng bổ sung như thế này.

Nếu giá trị bạn đã gửi làlong :

long value = getIntent().getLongExtra("Variable name which you sent as an extra", defaultValue(you can give it anything));

Nếu giá trị bạn gửi làString :

String value = getIntent().getStringExtra("Variable name which you sent as an extra");

Nếu giá trị bạn gửi làBoolean :

Boolean value = getIntent().getBooleanExtra("Variable name which you sent as an extra", defaultValue);

3
Xin lưu ý rằng tài liệu chỉ ra như sau: Thêm dữ liệu mở rộng vào mục đích. Tên phải bao gồm tiền tố gói, ví dụ: ứng dụng com.android.contacts sẽ sử dụng các tên như "com.android.contacts.Show ALL".
Serguei Fedorov

Đây là một bản sao của câu trả lời được bình chọn nhiều nhất đã có ở đó 2 năm trước câu trả lời này và câu trả lời của Sahil Mahajan Mj cũ hơn 1 năm. Chỉ khác biệt: ví dụ cho booleanlonggetters đáng nhận xét IMO, không phải là một câu trả lời.
Murmel

48

Nó giúp tôi nhìn thấy mọi thứ trong bối cảnh. Đây là hai ví dụ.

Truyền dữ liệu chuyển tiếp

nhập mô tả hình ảnh ở đây

Hoạt động chính

  • Đặt dữ liệu bạn muốn gửi trong Ý định với cặp khóa-giá trị. Xem câu trả lời này cho các quy ước đặt tên cho khóa.
  • Bắt đầu hoạt động thứ hai với startActivity.

MainActivity.java

public class MainActivity extends AppCompatActivity {

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

    // "Go to Second Activity" button click
    public void onButtonClick(View view) {

        // get the text to pass
        EditText editText = (EditText) findViewById(R.id.editText);
        String textToPass = editText.getText().toString();

        // start the SecondActivity
        Intent intent = new Intent(this, SecondActivity.class);
        intent.putExtra(Intent.EXTRA_TEXT, textToPass);
        startActivity(intent);
    }
}

Hoạt động thứ hai

  • Bạn sử dụng getIntent()để có được Intentbắt đầu hoạt động thứ hai. Sau đó, bạn có thể trích xuất dữ liệu với getExtras()và khóa bạn đã xác định trong hoạt động đầu tiên. Vì dữ liệu của chúng tôi là một Chuỗi, chúng tôi sẽ chỉ sử dụng getStringExtraở đây.

Thứ haiActivity.java

public class SecondActivity extends AppCompatActivity {

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

        // get the text from MainActivity
        Intent intent = getIntent();
        String text = intent.getStringExtra(Intent.EXTRA_TEXT);

        // use the text in a TextView
        TextView textView = (TextView) findViewById(R.id.textView);
        textView.setText(text);
    }
}

Truyền lại dữ liệu

nhập mô tả hình ảnh ở đây

Hoạt động chính

  • Bắt đầu Hoạt động thứ hai với startActivityForResult, cung cấp cho nó mã kết quả tùy ý.
  • Ghi đè onActivityResult. Điều này được gọi khi Hoạt động thứ hai kết thúc. Bạn có thể chắc chắn rằng đó thực sự là Hoạt động thứ hai bằng cách kiểm tra mã kết quả. (Điều này hữu ích khi bạn bắt đầu nhiều hoạt động khác nhau từ cùng một hoạt động chính.)
  • Trích xuất dữ liệu bạn nhận được từ sự trở lại Intent. Dữ liệu được trích xuất bằng cặp khóa-giá trị. Tôi có thể sử dụng bất kỳ chuỗi nào cho khóa nhưng tôi sẽ sử dụng chuỗi được xác định trước Intent.EXTRA_TEXTvì tôi đang gửi văn bản.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private static final int SECOND_ACTIVITY_REQUEST_CODE = 0;

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

    // "Go to Second Activity" button click
    public void onButtonClick(View view) {

        // Start the SecondActivity
        Intent intent = new Intent(this, SecondActivity.class);
        startActivityForResult(intent, SECOND_ACTIVITY_REQUEST_CODE);
    }

    // This method is called when the second activity finishes
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // check that it is the SecondActivity with an OK result
        if (requestCode == SECOND_ACTIVITY_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {

                // get String data from Intent
                String returnString = data.getStringExtra(Intent.EXTRA_TEXT);

                // set text view with string
                TextView textView = (TextView) findViewById(R.id.textView);
                textView.setText(returnString);
            }
        }
    }
}

Hoạt động thứ hai

  • Đặt dữ liệu mà bạn muốn gửi lại cho hoạt động trước đó vào một Intent. Dữ liệu được lưu trữ trong cặp Intentsử dụng khóa-giá trị. Tôi đã chọn sử dụng Intent.EXTRA_TEXTcho chìa khóa của tôi.
  • Đặt kết quả RESULT_OKvà thêm ý định giữ dữ liệu của bạn.
  • Gọi finish()để đóng Hoạt động thứ hai.

Thứ haiActivity.java

public class SecondActivity extends AppCompatActivity {

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

    // "Send text back" button click
    public void onButtonClick(View view) {

        // get the text from the EditText
        EditText editText = (EditText) findViewById(R.id.editText);
        String stringToPassBack = editText.getText().toString();

        // put the String to pass back into an Intent and close this activity
        Intent intent = new Intent();
        intent.putExtra(Intent.EXTRA_TEXT, stringToPassBack);
        setResult(RESULT_OK, intent);
        finish();
    }
}

3
Ồ, cảm ơn bạn! Đây là những gì tôi đang tìm kiếm. Nó khá rõ ràng khi sử dụng máy ảnh hoặc các thiết bị bên ngoài khác mà tôi mong đợi kết quả trở lại, nhưng tôi không nghĩ sẽ sử dụng nó trong nội bộ. Bạn là người đầu tiên đặt nó khá cởi mở.
dùng3195231

45

Lưu ý cập nhật rằng tôi đã đề cập đến việc sử dụng SharedPreference . Nó có một API đơn giản và có thể truy cập trong các hoạt động của ứng dụng. Nhưng đây là một giải pháp vụng về và là một rủi ro bảo mật nếu bạn vượt qua các dữ liệu nhạy cảm. Tốt nhất là sử dụng ý định. Nó có một danh sách rộng lớn các phương thức quá tải có thể được sử dụng để chuyển tốt hơn nhiều loại dữ liệu khác nhau giữa các hoạt động. Có một cái nhìn vào ý định.putExtra . Đây liên kết giới thiệu việc sử dụng putExtra khá tốt.

Khi truyền dữ liệu giữa các hoạt động, cách tiếp cận ưa thích của tôi là tạo ra một phương thức tĩnh cho hoạt động có liên quan bao gồm các tham số bắt buộc khởi chạy ý định. Mà sau đó cung cấp dễ dàng thiết lập và lấy tham số. Vì vậy, nó có thể trông như thế này

public class MyActivity extends Activity {
    public static final String ARG_PARAM1 = "arg_param1";
...
public static getIntent(Activity from, String param1, Long param2...) {
    Intent intent = new Intent(from, MyActivity.class);
        intent.putExtra(ARG_PARAM1, param1);
        intent.putExtra(ARG_PARAM2, param2);
        return intent;
}

....
// Use it like this.
startActivity(MyActvitiy.getIntent(FromActivity.this, varA, varB, ...));
...

Sau đó, bạn có thể tạo một ý định cho hoạt động dự định và đảm bảo bạn có tất cả các tham số. Bạn có thể thích nghi cho các mảnh vỡ. Một ví dụ đơn giản ở trên, nhưng bạn có được ý tưởng.


2
Tôi thích câu trả lời của bạn nhất ... Vượt qua nó thông qua ý định có nghĩa là hầu như mọi nơi tôi bắt đầu một hoạt động bạn sẽ phải nhớ để bao gồm sessionId. Bằng cách đưa nó vào SharedPreferences, bạn có thể nhận được nó bất cứ lúc nào từ bất kỳ hoạt động nào. : 0)
bytebender

@bytebender Tôi biết điều này hơi muộn cho phản hồi, tôi đánh giá cao rằng bạn thích câu trả lời ban đầu của tôi vì tính tương tự của nó, nhưng tôi sẽ cẩn thận lưu trữ ID phiên trong các tùy chọn chia sẻ. Nếu bạn phải lưu trữ nó trên bộ nhớ cứng thì hãy sử dụng mã hóa. Nếu bạn có thể sử dụng khung xác thực sử dụng JWT, nó sẽ bao gồm refreshTokens an toàn hơn cho việc lưu trữ lâu dài và sau đó giữ mã thông báo phiên hiện tại làm tài sản công cộng của đối tượng Ứng dụng tùy chỉnh để dễ dàng truy cập mã xác thực và giảm chi phí hoạt động chữ ký ý định.
tức giận

38

Hãy thử làm như sau:

Tạo một lớp "người trợ giúp" đơn giản (nhà máy cho ý định của bạn), như thế này:

import android.content.Intent;

public class IntentHelper {
    public static final Intent createYourSpecialIntent(Intent src) {
          return new Intent("YourSpecialIntent").addCategory("YourSpecialCategory").putExtras(src);
    }
}

Đây sẽ là nhà máy cho tất cả các ý định của bạn. Bất cứ khi nào bạn cần một Ý định mới, hãy tạo một phương thức nhà máy tĩnh trong IntentHelper. Để tạo một ý định mới, bạn chỉ cần nói như thế này:

IntentHelper.createYourSpecialIntent(getIntent());

Trong hoạt động của bạn. Khi bạn muốn "lưu" một số dữ liệu trong "phiên", chỉ cần sử dụng như sau:

IntentHelper.createYourSpecialIntent(getIntent()).putExtra("YOUR_FIELD_NAME", fieldValueToSave);

Và gửi ý định này. Trong mục tiêu Hoạt động, trường của bạn sẽ có sẵn như sau:

getIntent().getStringExtra("YOUR_FIELD_NAME");

Vì vậy, bây giờ chúng ta có thể sử dụng Intent giống như phiên cũ (như trong servlets hoặc JSP ).


28

Bạn cũng có thể vượt qua đối tượng lớp tùy chỉnh bằng cách làm một parcelable lớp. Cách tốt nhất để làm cho nó có thể phân chia được là viết lớp của bạn và sau đó chỉ cần dán nó vào một trang web như http://www.parcelabler.com/ . Nhấp vào xây dựng và bạn sẽ nhận được mã mới. Sao chép tất cả điều này và thay thế nội dung lớp ban đầu. Sau đó-

Intent intent = new Intent(getBaseContext(), NextActivity.class);
Foo foo = new Foo();
intent.putExtra("foo", foo);
startActivity(intent);

và nhận kết quả trong NextActivity như-

Foo foo = getIntent().getExtras().getParcelable("foo");

Bây giờ bạn có thể chỉ cần sử dụng đối tượng foo như bạn đã sử dụng.


23

Một cách khác là sử dụng trường tĩnh công khai nơi bạn lưu trữ dữ liệu, nghĩa là:

public class MyActivity extends Activity {

  public static String SharedString;
  public static SomeObject SharedObject;

//...

5
Tôi thực sự tự hỏi tại sao đề xuất của bạn không nhận được phiếu bầu, nó đơn giản và thiết thực hơn.
Porizm

7
Ừm ... điều này có vi phạm nguyên tắc OO không?
Christian Vielma

2
Tốt Hoạt động tốt cho bạn hay không, tôi thích cách này vì nó dễ theo dõi hơn, nhưng nó có thể trở nên rất bẩn rất nhanh ...
ComputerSaysKhông

2
Tại sao bạn nói điều này bị bẩn? Không phải iOS làm điều này để truyền dữ liệu giữa các trình điều khiển chế độ xem bằng cách đặt "thuộc tính" tương tự như thế này sao? Điều này dễ dàng hơn nhiều so với việc sử dụng ý định
Terry Bu

2
Có, bạn chuyển dữ liệu giữa các bộ điều khiển xem, nhưng không có thuộc tính tĩnh . Vấn đề là nó không phải là một tài sản trong trường hợp hoạt động mong muốn. Cách Android khởi chạy các hoạt động thông qua startActivity (), nó không ngay lập tức khởi tạo đối tượng và cho phép nhà phát triển đặt một biến thể hiện. Thật là khó chịu ...
Shawn

20

Cách thuận tiện nhất để truyền dữ liệu giữa các hoạt động là bằng cách truyền ý định. Trong hoạt động đầu tiên từ nơi bạn muốn gửi dữ liệu, bạn nên thêm mã,

String str = "My Data"; //Data you want to send
Intent intent = new Intent(FirstActivity.this, SecondActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("name",str); //Here you will add the data into intent to pass bw activites
v.getContext().startActivity(intent);

Bạn cũng nên nhập

import android.content.Intent;

Sau đó, trong Acitvity tiếp theo (SecondActivity), bạn nên truy xuất dữ liệu từ mục đích sử dụng mã sau đây.

String name = this.getIntent().getStringExtra("name");

2
Đây là một bản sao của câu trả lời được bình chọn nhiều nhất hàng đầu đã có hơn 1 năm.
Murmel

19

Bạn có thể sử dụng SharedPreferences...

  1. Ghi nhật ký. Id phiên lưu trữ thời gian trongSharedPreferences

    SharedPreferences preferences = getSharedPreferences("session",getApplicationContext().MODE_PRIVATE);
    Editor editor = preferences.edit();
    editor.putString("sessionId", sessionId);
    editor.commit();
  2. Đăng xuất. Thời gian tìm nạp id phiên trong sharedpreferences

    SharedPreferences preferences = getSharedPreferences("session", getApplicationContext().MODE_PRIVATE);
    String sessionId = preferences.getString("sessionId", null);

Nếu bạn không có id phiên cần thiết, hãy xóa chia sẻ:

SharedPreferences settings = context.getSharedPreferences("session", Context.MODE_PRIVATE);
settings.edit().clear().commit();

Điều đó rất hữu ích, bởi vì một lần bạn lưu giá trị và sau đó lấy bất kỳ nơi nào của hoạt động.


17

Cách tiếp cận tiêu chuẩn.

Intent i = new Intent(this, ActivityTwo.class);
AutoCompleteTextView textView = (AutoCompleteTextView) findViewById(R.id.autocomplete);
String getrec=textView.getText().toString();
Bundle bundle = new Bundle();
bundle.putString(“stuff”, getrec);
i.putExtras(bundle);
startActivity(i);

Bây giờ trong hoạt động thứ hai của bạn lấy dữ liệu của bạn từ gói:

Nhận gói

Bundle bundle = getIntent().getExtras();

Trích xuất dữ liệu

String stuff = bundle.getString(“stuff”); 

1
Sao y như đã được đề xuất bởi PRABEESH RK vào năm 2012. Và có thể được giảm xuống thành i.putExtras()/ getIntent().getString()được đề xuất bởi 6 câu trả lời khác ...
Murmel

17

Từ hoạt động

 int n= 10;
 Intent in = new Intent(From_Activity.this,To_Activity.class);
 Bundle b1 = new Bundle();
 b1.putInt("integerNumber",n);
 in.putExtras(b1);
 startActivity(in);

Hoạt động

 Bundle b2 = getIntent().getExtras();
 int m = 0;
 if(b2 != null)
  {
     m = b2.getInt("integerNumber");
  }

1
Sao y: Cách Bundletiếp cận dựa trên đã được PRABEESH RK đề xuất vào năm 2012 và Ajay Venugopal , Krishna . Và có thể được giảm xuống i.putExtras()/ getIntent().getString()được đề xuất bởi 8 câu trả lời khác ...
Murmel

11

Bạn có thể gửi dữ liệu giữa các hoạt động bằng cách sử dụng đối tượng mục đích. Hãy xem xét bạn có hai hoạt động là FirstActivitySecondActivity.

Bên trong FirstActivity:

Sử dụng ý định:

i = new Intent(FirstActivity.this,SecondActivity.class);
i.putExtra("key", value);
startActivity(i)

Bên trong SecondActivity

Bundle bundle= getIntent().getExtras();

Bây giờ bạn có thể sử dụng các phương thức lớp gói khác nhau để nhận các giá trị được truyền từ FirstActivity bằng Key.

Ví dụ như bundle.getString("key"), bundle.getDouble("key"), bundle.getInt("key"), vv


1
Sao y: Cách Bundletiếp cận dựa trên đã được PRABEESH RK đề xuất vào năm 2012 và Ajay Venugopal . Và có thể được giảm xuống i.putExtras()/ getIntent().getString()được đề xuất bởi 7 câu trả lời khác ...
Murmel

11

Nếu bạn muốn chuyển bitmap giữa Activites / Fragment


Hoạt động

Để vượt qua một bitmap giữa các hoạt động

Intent intent = new Intent(this, Activity.class);
intent.putExtra("bitmap", bitmap);

Và trong lớp Hoạt động

Bitmap bitmap = getIntent().getParcelableExtra("bitmap");

Miếng

Để vượt qua một bitmap giữa các mảnh

SecondFragment fragment = new SecondFragment();
Bundle bundle = new Bundle();
bundle.putParcelable("bitmap", bitmap);
fragment.setArguments(bundle);

Để nhận được bên trong SecondFragment

Bitmap bitmap = getArguments().getParcelable("bitmap");

Chuyển bitmap lớn

Nếu bạn nhận được giao dịch liên kết không thành công, điều này có nghĩa là bạn đang vượt quá bộ đệm giao dịch liên kết bằng cách chuyển phần tử lớn từ hoạt động này sang hoạt động khác.

Vì vậy, trong trường hợp đó, bạn phải nén bitmap thành một mảng của byte và sau đó giải nén nó trong một hoạt động khác , như thế này

Trong FirstActivity

Intent intent = new Intent(this, SecondActivity.class);

ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPG, 100, stream);
byte[] bytes = stream.toByteArray(); 
intent.putExtra("bitmapbytes",bytes);

Và trong phần thứ hai

byte[] bytes = getIntent().getByteArrayExtra("bitmapbytes");
Bitmap bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);

9
Intent intent = new Intent(YourCurrentActivity.this, YourActivityName.class);
intent.putExtra("NAme","John");
intent.putExtra("Id",1);
startActivity(intent);

Bạn có thể lấy nó trong một hoạt động khác. Hai lối:

int id = getIntent.getIntExtra("id", /* defaltvalue */ 2);

Cách thứ hai là:

Intent i = getIntent();
String name = i.getStringExtra("name");


8

Đây là thực tiễn tốt nhất của tôi và nó giúp ích rất nhiều khi dự án rất lớn và phức tạp.

Giả sử tôi có 2 hoạt động, LoginActivityHomeActivity. Tôi muốn chuyển 2 tham số (tên người dùng và mật khẩu) từ LoginActivityđến HomeActivity.

Đầu tiên, tôi tạo HomeIntent

public class HomeIntent extends Intent {

    private static final String ACTION_LOGIN = "action_login";
    private static final String ACTION_LOGOUT = "action_logout";

    private static final String ARG_USERNAME = "arg_username";
    private static final String ARG_PASSWORD = "arg_password";


    public HomeIntent(Context ctx, boolean isLogIn) {
        this(ctx);
        //set action type
        setAction(isLogIn ? ACTION_LOGIN : ACTION_LOGOUT);
    }

    public HomeIntent(Context ctx) {
        super(ctx, HomeActivity.class);
    }

    //This will be needed for receiving data
    public HomeIntent(Intent intent) {
        super(intent);
    }

    public void setData(String userName, String password) {
        putExtra(ARG_USERNAME, userName);
        putExtra(ARG_PASSWORD, password);
    }

    public String getUsername() {
        return getStringExtra(ARG_USERNAME);
    }

    public String getPassword() {
        return getStringExtra(ARG_PASSWORD);
    }

    //To separate the params is for which action, we should create action
    public boolean isActionLogIn() {
        return getAction().equals(ACTION_LOGIN);
    }

    public boolean isActionLogOut() {
        return getAction().equals(ACTION_LOGOUT);
    }
}

Đây là cách tôi truyền dữ liệu trong LoginActivity của mình

public class LoginActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        String username = "phearum";
        String password = "pwd1133";
        final boolean isActionLogin = true;
        //Passing data to HomeActivity
        final HomeIntent homeIntent = new HomeIntent(this, isActionLogin);
        homeIntent.setData(username, password);
        startActivity(homeIntent);

    }
}

Bước cuối cùng, đây là cách tôi nhận dữ liệu trong HomeActivity

public class HomeActivity extends AppCompatActivity {

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

        //This is how we receive the data from LoginActivity
        //Make sure you pass getIntent() to the HomeIntent constructor
        final HomeIntent homeIntent = new HomeIntent(getIntent());
        Log.d("HomeActivity", "Is action login?  " + homeIntent.isActionLogIn());
        Log.d("HomeActivity", "username: " + homeIntent.getUsername());
        Log.d("HomeActivity", "password: " + homeIntent.getPassword());
    }
}

Làm xong! Thật tuyệt :) Tôi chỉ muốn chia sẻ kinh nghiệm của tôi. Nếu bạn làm việc trong dự án nhỏ thì đây không phải là vấn đề lớn. Nhưng khi bạn làm việc trong dự án lớn, sẽ thực sự đau đớn khi bạn muốn thực hiện tái cấu trúc hoặc sửa lỗi.


7

Bổ sung Trả lời: Quy ước đặt tên cho Chuỗi khóa

Quá trình truyền dữ liệu thực tế đã được trả lời, tuy nhiên hầu hết các câu trả lời đều sử dụng chuỗi mã hóa cứng cho tên khóa trong Ý định. Điều này thường tốt khi chỉ được sử dụng trong ứng dụng của bạn. Tuy nhiên, tài liệu khuyến nghị sử dụng các EXTRA_*hằng số cho các kiểu dữ liệu được tiêu chuẩn hóa.

Ví dụ 1: Sử dụng Intent.EXTRA_*các phím

Hoạt động đầu tiên

Intent intent = new Intent(getActivity(), SecondActivity.class);
intent.putExtra(Intent.EXTRA_TEXT, "my text");
startActivity(intent);

Hoạt động thứ hai:

Intent intent = getIntent();
String myText = intent.getExtras().getString(Intent.EXTRA_TEXT);

Ví dụ 2: Xác định static finalkhóa riêng của bạn

Nếu một trong các Intent.EXTRA_*Chuỗi không phù hợp với nhu cầu của bạn, bạn có thể xác định chuỗi của riêng mình khi bắt đầu hoạt động đầu tiên.

static final String EXTRA_STUFF = "com.myPackageName.EXTRA_STUFF";

Bao gồm tên gói chỉ là một quy ước nếu bạn chỉ sử dụng khóa trong ứng dụng của riêng bạn. Nhưng điều cần thiết là tránh xung đột khi đặt tên nếu bạn đang tạo một loại dịch vụ mà các ứng dụng khác có thể gọi bằng Ý định.

Hoạt động đầu tiên:

Intent intent = new Intent(getActivity(), SecondActivity.class);
intent.putExtra(EXTRA_STUFF, "my text");
startActivity(intent);

Hoạt động thứ hai:

Intent intent = getIntent();
String myText = intent.getExtras().getString(FirstActivity.EXTRA_STUFF);

Ví dụ 3: Sử dụng khóa tài nguyên Chuỗi

Mặc dù không được đề cập trong tài liệu, câu trả lời này khuyên bạn nên sử dụng tài nguyên Chuỗi để tránh phụ thuộc giữa các hoạt động.

chuỗi DOM

 <string name="EXTRA_STUFF">com.myPackageName.MY_NAME</string>

Hoạt động đầu tiên

Intent intent = new Intent(getActivity(), SecondActivity.class);
intent.putExtra(getString(R.string.EXTRA_STUFF), "my text");
startActivity(intent);

Hoạt động thứ hai

Intent intent = getIntent();
String myText = intent.getExtras().getString(getString(R.string.EXTRA_STUFF));

7

Bạn có thể dùng Intent

Intent mIntent = new Intent(FirstActivity.this, SecondActivity.class);
mIntent.putExtra("data", data);
startActivity(mIntent);

Một cách khác có thể là sử dụng mẫu singleton :

public class DataHolder {

 private static DataHolder dataHolder;
 private List<Model> dataList;

 public void setDataList(List<Model>dataList) {
    this.dataList = dataList;
 }

 public List<Model> getDataList() {
    return dataList;
 }

 public synchronized static DataHolder getInstance() {
    if (dataHolder == null) {
       dataHolder = new DataHolder();
    }
    return dataHolder;
 }
}

Từ tính năng đầu tiên của bạn

private List<Model> dataList = new ArrayList<>();
DataHolder.getInstance().setDataList(dataList);

Về tính năng thứ hai

private List<Model> dataList = DataHolder.getInstance().getDataList();

Duplicate: Cách tiếp cận mục tiêu đã được đề xuất bởi các đầu bình chọn nhất câu trả lờicâu trả lời Sahil Mahajan Mj của và các câu trả lời Mayank Saini của. Câu trả lời Md Rahman , Dilavar M của câu trả lời , câu trả lời android phát triển của , sahulab . Singleton: Câu trả lời của Rodion Altshuler
Murmel

6

Việc truyền dữ liệu giữa các hoạt động chủ yếu bằng phương tiện của một đối tượng có ý định.

Trước tiên, bạn phải đính kèm dữ liệu vào đối tượng mục đích với việc sử dụng Bundlelớp. Sau đó gọi hoạt động bằng cách sử dụng một trong hai startActivity()hoặc startActivityForResult()phương thức.

Bạn có thể tìm thêm thông tin về nó, với một ví dụ từ bài đăng trên blog Truyền dữ liệu cho một Hoạt động .


Điều này ít nhiều giống với việc sử dụng các phương thức Intent cung cấp trực tiếp ( Intent#putExtra()). Nhưng thêm một cái khác Bundlevà làm cho mọi thứ phức tạp hơn.
Murmel

6

Bạn có thể thử Tùy chọn chia sẻ, nó có thể là một lựa chọn tốt để chia sẻ dữ liệu giữa các hoạt động

Để lưu id phiên -

SharedPreferences pref = myContexy.getSharedPreferences("Session 
Data",MODE_PRIVATE);
SharedPreferences.Editor edit = pref.edit();
edit.putInt("Session ID", session_id);
edit.commit();

Để có được chúng -

SharedPreferences pref = myContexy.getSharedPreferences("Session Data", MODE_PRIVATE);
session_id = pref.getInt("Session ID", 0);

Sao y: Cách tiếp cận này đã được Ravi Parsania đạo diễn vào năm 2014
Murmel

5

Bắt đầu một hoạt động khác từ hoạt động này vượt qua các tham số thông qua Bundle Object

Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("USER_NAME", "xyz@gmail.com");
startActivity(intent);

Truy xuất hoạt động khác (YourActivity)

String s = getIntent().getStringExtra("USER_NAME");

Điều này là ok cho loại dữ liệu đơn giản. Nhưng nếu bạn muốn truyền dữ liệu phức tạp vào giữa hoạt động thì trước tiên bạn cần phải tuần tự hóa nó.

Ở đây chúng tôi có Mô hình nhân viên

class Employee{
    private String empId;
    private int age;
    print Double salary;

    getters...
    setters...
}

Bạn có thể sử dụng lib Gson do google cung cấp để tuần tự hóa dữ liệu phức tạp như thế này

String strEmp = new Gson().toJson(emp);
Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("EMP", strEmp);
startActivity(intent);

Bundle bundle = getIntent().getExtras();
String empStr = bundle.getString("EMP");
            Gson gson = new Gson();
            Type type = new TypeToken<Employee>() {
            }.getType();
            Employee selectedEmp = gson.fromJson(empStr, type);

5

Kotlin

Chuyển từ hoạt động đầu tiên

val intent = Intent(this, SecondActivity::class.java)
intent.putExtra("key", "value")
startActivity(intent)

Tham gia vào hoạt động thứ hai

val value = getIntent().getStringExtra("key")

Gợi ý

Luôn đặt các khóa trong tệp không đổi để quản lý nhiều hơn.

companion object {
    val KEY = "key"
}

4
/*
 * If you are from transferring data from one class that doesn't
 * extend Activity, then you need to do something like this.
 */ 

public class abc {
    Context context;

    public abc(Context context) {
        this.context = context;
    }

    public void something() {
        context.startactivity(new Intent(context, anyone.class).putextra("key", value));
    }
}

4

Charlie Collins đã cho tôi một câu trả lời hoàn hảo bằng cách sử dụng Application.class. Tôi đã không biết rằng chúng ta có thể phân lớp nó dễ dàng như vậy. Dưới đây là một ví dụ đơn giản hóa bằng cách sử dụng một lớp ứng dụng tùy chỉnh.

AndroidManifest.xml

Đưa ra android:namethuộc tính để sử dụng lớp ứng dụng của riêng bạn.

...
<application android:name="MyApplication"
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
....

MyApplication.java

Sử dụng này như một chủ sở hữu tài liệu tham khảo toàn cầu. Nó hoạt động tốt trong cùng một quá trình.

public class MyApplication extends Application {
    private MainActivity mainActivity;

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

    public void setMainActivity(MainActivity activity) { this.mainActivity=activity; }
    public MainActivity getMainActivity() { return mainActivity; }
}

MainActivity.java

Đặt tham chiếu "singleton" toàn cầu cho phiên bản ứng dụng.

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ((MyApplication)getApplication()).setMainActivity(this);
    }
    ...

}

MyPreferences.java

Một ví dụ đơn giản trong đó tôi sử dụng một hoạt động chính từ một ví dụ hoạt động khác.

public class MyPreferences extends PreferenceActivity
            implements SharedPreferences.OnSharedPreferenceChangeListener {
    @SuppressWarnings("deprecation")
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
        PreferenceManager.getDefaultSharedPreferences(this)
            .registerOnSharedPreferenceChangeListener(this);
    }

    @Override
    public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
        if (!key.equals("autostart")) {
            ((MyApplication)getApplication()).getMainActivity().refreshUI();
        }
    }
}

4

Gần đây tôi đã phát hành Vapor API , một khung công tác Android có hương vị jQuery giúp mọi công việc như thế này trở nên đơn giản hơn. Như đã đề cập, SharedPreferenceslà một cách bạn có thể làm điều này.

VaporSharedPreferencesđược triển khai dưới dạng Singleton vì vậy đó là một tùy chọn và trong Vapor API, nó có một .put(...)phương thức quá tải nặng nề, do đó bạn không phải lo lắng rõ ràng về kiểu dữ liệu bạn đang cam kết - miễn là nó được hỗ trợ. Nó cũng trôi chảy, vì vậy bạn có thể xâu chuỗi các cuộc gọi:

$.prefs(...).put("val1", 123).put("val2", "Hello World!").put("something", 3.34);

Nó cũng tùy chọn tự động thay đổi và thống nhất quy trình đọc và viết dưới mức để bạn không cần truy xuất một Trình chỉnh sửa rõ ràng như bạn làm trong Android tiêu chuẩn.

Ngoài ra, bạn có thể sử dụng một Intent. Trong API Vapor, bạn cũng có thể sử dụng .put(...)phương thức nạp chồng có thể xâu chuỗi trên VaporIntent:

$.Intent().put("data", "myData").put("more", 568)...

Và vượt qua nó như một phần phụ, như đã đề cập trong các câu trả lời khác. Bạn có thể truy xuất các tính năng bổ sung từ của bạn Activityvà hơn nữa nếu bạn đang sử dụng việc VaporActivitynày được thực hiện cho bạn một cách tự động để bạn có thể sử dụng:

this.extras()

Để lấy chúng ở đầu kia trong Activitybạn chuyển sang.

Hy vọng đó là một số quan tâm :)


@BaneeIshaqueK xin lỗi, đã không duy trì điều này trong một thời gian. Đã cập nhật liên kết để trỏ trực tiếp đến Github cho dự án trong trường hợp nó giúp. ps. Không chắc tôi đã nghĩ gì về giấy phép đó ... xin lỗi
Darius

4

Hoạt động đầu tiên:

Intent intent = new Intent(getApplicationContext(), ClassName.class);
intent.putExtra("Variable name", "Value you want to pass");
startActivity(intent);

Hoạt động thứ hai:

String str= getIntent().getStringExtra("Variable name which you sent as an extra");

4

Bạn có thể truyền dữ liệu giữa các hoạt động trong ứng dụng theo 3 cách

  1. Ý định
  2. SharedPreferences
  3. Ứng dụng

truyền dữ liệu trong ý định có một số giới hạn. Đối với lượng dữ liệu lớn, bạn có thể sử dụng chia sẻ dữ liệu ở cấp Ứng dụng và bằng cách lưu trữ nó trong SharedPreference làm cho kích thước ứng dụng của bạn tăng lên


3

Sử dụng một lớp toàn cầu:

public class GlobalClass extends Application
{
    private float vitamin_a;


    public float getVitaminA() {
        return vitamin_a;
    }

    public void setVitaminA(float vitamin_a) {
        this.vitamin_a = vitamin_a;
    }
}

Bạn có thể gọi setters và getters của lớp này từ tất cả các lớp khác. Để làm điều đó, bạn cần tạo một GlobalClass-Object trong mọi Actitity:

GlobalClass gc = (GlobalClass) getApplication();

Sau đó, bạn có thể gọi ví dụ:

gc.getVitaminA()

Ứng dụng ghi đè - đây là bản sao câu trả lời của
Whome
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.