如何在Android应用程序中传递活动之间的数据?

1533

我有这样一个情况,通过登录页面登录后,每个活动页面上都会有一个“退出”按钮

点击“退出”后,我将传递已登录用户的会话ID以进行注销。 有人能指导我如何使会话ID在所有活动中可用吗?

这种情况是否有任何替代方案?


18
我使用了sharedpreference,它对于在“记住密码”功能中保存登录数据也很有用。 - shareef
这对我有效。 感谢Darshan Computing。 - matasoy
这篇回答可能会对您有所帮助:https://dev59.com/RHE85IYBdhLWcg3whD7k#37774966 - Yessy
对于这种情况,尝试使用commonUtils类和sharedpreferences方法... 这将使代码保持清晰,并将相关数据放在一个地方。您将能够仅通过清除特定的偏好文件的一个方法来清除特定集合的数据,而不会清除任何默认应用程序数据... - Muahmmad Tayyib
53个回答

23

来自活动

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);

前往活动

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

23

在活动之间传递数据的最方便方法是通过传递意图。在您想要发送数据的第一个活动中,您应该添加以下代码:

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);

你还应该导入

import android.content.Intent;

接下来在第二个Activity(SecondActivity)中,您应该使用以下代码从意图中检索数据。

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

2
这是一个副本,复制了得票最多的答案,而那个答案甚至比它早一年。 - Murmel

23

您可以使用SharedPreferences...

  1. 记录。将时间存储到SharedPreferences中的会话ID。

SharedPreferences preferences = getSharedPreferences("session",getApplicationContext().MODE_PRIVATE);
Editor editor = preferences.edit();
editor.putString("sessionId", sessionId);
editor.commit();
  • 退出登录。从SharedPreferences中获取会话ID的时间

  • SharedPreferences preferences = getSharedPreferences("session", getApplicationContext().MODE_PRIVATE);
    String sessionId = preferences.getString("sessionId", null);
    
    如果您没有所需的会话 ID,则删除 sharedpreferences:

    如果您没有必要的会话 ID,则删除 sharedpreferences:

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

    这非常有用,因为您可以保存值,然后在任何活动中检索。


    19

    标准方法。

    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);
    

    现在在你的第二个活动中,从Bundle中检索你的数据:

    获取Bundle

    Bundle bundle = getIntent().getExtras();
    

    提取数据...

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

    1
    已经在2012年由PRABEESH R K提出了重复的建议。而且可以简化为i.putExtras()/getIntent().getString(),这是其他6个答案提出的... - Murmel

    19

    Kotlin

    从第一个活动传递

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

    进入第二个活动

    val value = intent.getStringExtra("key")
    

    建议

    始终将键放入常量文件中,以便更好地管理。

    companion object {
        val KEY = "key"
    }
    

    获取传递过来的值,键名为“key”。 - J A S K I E R

    13

    如果您想在活动/片段之间传输位图


    活动

    要在活动之间传递位图

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

    在Activity类中

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

    片段

    在片段之间传递位图

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

    进入 SecondFragment 内部

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

    传输大位图

    如果您遇到 "failed binder transaction" 错误,则表示您正在通过从一个活动传输大元素到另一个活动而超出绑定器事务缓冲区。

    在这种情况下,您需要将位图压缩为字节数组,然后在另一个活动中解压缩它,如下所示:

    在 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);
    

    并且在SecondActivity中

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

    13

    您可以使用Intent对象在活动之间发送数据。

    假设您有两个活动,分别为 FirstActivity SecondActivity

    在FirstActivity中:

    使用Intent:

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

    在SecondActivity内部

    Bundle bundle= getIntent().getExtras();
    

    现在,您可以使用不同的Bundle类方法按键获取从FirstActivity传递的值。

    例如:bundle.getString("key")bundle.getDouble("key")bundle.getInt("key")等。


    1
    已经在2012年由PRABEESH R KAjay Venugopal提出了“Bundle”方法,而且可以通过7个其他答案中提出的i.putExtras() / getIntent().getString()来简化。 - Murmel

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

    您可以在另一个活动中检索它。 两种方法:

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

    第二种方式是:

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

    这是一个重复的问题,与3年前的最高票答案Sahil Mahajan Mj的答案Mayank Saini的答案Md. Rahman的答案相同。 - Murmel

    10

    这是我的最佳实践,当项目非常庞大和复杂时它非常有帮助。

    假设我有两个活动:LoginActivityHomeActivity。我想从 LoginActivity 传递两个参数(用户名和密码)到 HomeActivity

    首先,我创建我的 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);
        }
    }
    

    这是我在 LoginActivity 中如何传递数据的方法

    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);
    
        }
    }
    

    最后一步,以下是我在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());
        }
    }
    

    完成了!太棒了 :) 我只是想分享我的经验。如果你正在处理小项目,这不应该是什么大问题。但当你在处理大项目时,想要进行重构或修复错误时真的很痛苦。


    10

    补充回答:关于键名命名约定

    传递数据的实际过程已经被回答了,但是大多数答案在Intent中使用硬编码字符串来命名键名。当仅在您的应用程序中使用时,这通常是可以接受的。然而,文档建议使用 EXTRA_*常量来标准化数据类型。

    示例1:使用 Intent.EXTRA_*

    第一个活动

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

    第二个活动:

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

    示例 2:定义自己的 static final

    如果 Intent.EXTRA_ * 字符串中没有适合您需要的内容,您可以在第一个活动的开头定义自己的字符串。

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

    如果你仅在自己的应用程序中使用键,则包名只是一种约定。但是,如果你创建了某种服务供其他应用程序使用Intent调用,则必须使用包名以避免命名冲突。

    第一个活动:

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

    第二个活动:

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

    示例 3:使用字符串资源键

    虽然文档中没有提到,但是这个答案建议使用字符串资源,以避免活动之间的依赖关系。

    strings.xml

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

    第一项活动

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

    第二个活动

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

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接