将数据传递给主Activity后丢失

5
那个问题让我头疼了几天都没有结果。简而言之,我有两个Activities(活动),为了举例,我将称它们为MainActivitySearchActivity。在MainActivity中,有一个按钮可以带你到一个搜索界面,也就是SearchActivity,那里有一个预设值的按钮,我想要把这个值传回MainActivity。到此为止,一切都很好。我点击调试器中的按钮,我能看到我的额外值,下一个断点是在MainActivity中的onCreate方法,但当我获取额外值时,什么也没有,全部都消失了。所以这里是重要的部分,代码如下:

MainActivity.class

public class MainActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


        btnSearch.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent search = new Intent(v.this, SearchActivity.class);
                startActivityForResult(search, SEARCH_VIDEO_REQUEST);
            }
        });
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == SEARCH_VIDEO_REQUEST) {
            if (resultCode == RESULT_OK) {
                String url = data.getExtras().getString("VIDEO_URL");
                if (url != null) {
                    txtUrl.setText(url);
                }
            }
        }
    }
}

SearchActivity.class

public class SearchActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        btnSend.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                String videoUrl = "http://video-url.com";
                Intent data = new Intent(SearchActivity.this, MainActivity.class);
                data.putExtra("VIDEO_URL", videoUrl);
                setResult(RESULT_OK, data);
                finish();
            }
        });
    }
}

AndroidManifest.xml

<activity
    android:name="com.project.MainActivity"
    android:label="@string/app_name"
    android:configChanges="keyboardHidden|orientation|screenSize"
    android:theme="@android:style/Theme.Black.NoTitleBar"
    android:screenOrientation="portrait">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.MEDIA_MOUNTED"/>
        <data android:scheme="file"/>
    </intent-filter>
</activity>
<activity
    android:name="com.project.SearchActivity"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.NoTitleBar"
    android:screenOrientation="portrait">
</activity>

这段代码在我的端上似乎可以工作。从这行代码 "Intent search = new Intent(v.this, SearchActivity.class);" 中的 v.this 是什么? - Bogdan Zurac
“V” 是 MainActivity 视图,“public void onClick(View v)” 是我传递给按钮事件的方法。我尝试使用 MainActivity.this,但出现了相同的问题。 - Alex Rashkov
8个回答

2
问题在于返回结果的类。
正如Mikel在另一个答案中指出的那样: Intent(Context packageContext, Class cls) API级别1中添加 创建特定组件的意图。所有其他字段(操作、数据、类型、类)都为空,尽管它们可以稍后通过显式调用进行修改。这提供了一种方便的方式来创建一个意图,该意图旨在执行硬编码的类名,而不是依靠系统为您找到适当的类;有关此操作的影响,请参阅setComponent(ComponentName)。
您没有明确设置数据参数,正如上面的文档所述,而是尝试向空数据对象添加额外的内容,这将失败。
相反,我会将您的类更改为以下内容:
public class SearchActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        btnSend.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                String videoUrl = "http://video-url.com";
                Intent data = new Intent();
                data.putExtra("VIDEO_URL", videoUrl);
                setResult(RESULT_OK, data);
                finish();
            }
        });
    }
}

这将初始化您的Intent并允许您向其中添加额外数据(这也是您通常会发送数据的正常方式,通常不需要发送与特定Intent相关联的结果)。

1
我复制了你的代码并尝试在我的设备上复制你的项目,我添加了一些行以便我可以运行它,例如布局等...以下是使用的代码。

MainActivity.java

package com.example.stackoverflow;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {

final MainActivity mainActivity = this;
final int SEARCH_VIDEO_REQUEST = 1;
TextView returntext;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    returntext = (TextView)findViewById(R.id.returnt);
    Button btnSearch = (Button)findViewById(R.id.btnSearch);
    btnSearch.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent search = new Intent(MainActivity.this, SearchActivity.class);
            startActivityForResult(search, SEARCH_VIDEO_REQUEST);
        }
    });
}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    Log.d("ret", "returned data is: "+ data);
    // super.onActivityResult(requestCode, resultCode, data);
    Log.d("ret", "returned data is: "+ data);
    if (requestCode == SEARCH_VIDEO_REQUEST) {
        if (resultCode == RESULT_OK) {
            String url = data.getExtras().getString("VIDEO_URL");
            if (url != null) {
                returntext.setText(url);
            }
        }
    }
}
}

SearchActivity.java

package com.example.stackoverflow;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class SearchActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
    setContentView(R.layout.search);

    Button  btnSend = (Button)findViewById(R.id.searchret);
    btnSend.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            String videoUrl = "http://video-url.com";
            Intent data = new Intent(SearchActivity.this, MainActivity.class);
            data.putExtra("VIDEO_URL", videoUrl);
            setResult(RESULT_OK, data);
            finish();
        }
    });
}
}

ManifestFile
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.stackoverflow"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="17" />

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".MainActivity"
        android:configChanges="keyboardHidden|orientation|screenSize"
        android:label="@string/app_name"
        android:screenOrientation="portrait"
        android:theme="@android:style/Theme.Black.NoTitleBar" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

    </activity>
    <activity
        android:name=".SearchActivity"
        android:label="@string/app_name"
        android:screenOrientation="portrait"
        android:theme="@android:style/Theme.NoTitleBar" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>

    </activity>
</application>

activity_main.xml(主活动的布局)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >

<TextView
    android:id="@+id/textView1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Main Activity Screen" />

<Button
    android:id="@+id/btnSearch"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignRight="@+id/textView1"
    android:layout_below="@+id/textView1"
    android:layout_marginRight="26dp"
    android:layout_marginTop="140dp"
    android:text="Button" />

    <TextView
        android:id="@+id/returnt"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="10dp"
    android:textSize="12dp"
    android:textColor="#454545"
    android:gravity="center_horizontal"
    android:layout_alignParentBottom="true"
    android:text="received text.." />

search.xml(搜索活动的布局)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
    android:id="@+id/textViewkj1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Search Screen" />

<Button
    android:id="@+id/searchret"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginRight="26dp"
    android:layout_marginTop="140dp"
    android:text="Search Screen Button" />

我已将项目导出为一个存档文件,以便您可以轻松地导入并在本地测试。这个方法运行良好,所以您可以与您的工作区中的内容进行比较。 下载此处

希望这能有所帮助,祝好!


1
您正在使用键“YOUTUBE_URL”来保存额外的信息,使用键“VIDEO_URL”来检索它,但该键不存在。请更改。
String url = data.getExtras().getString("VIDEO_URL");

to

String url = data.getExtras().getString("YOUTUBE_URL");

此外,您正在创建一个新的 MainActivity 实例,以您创建 Intent 的方式。请将其更改为:
Intent data = new Intent();  // empty constructor
            data.putExtra("YOUTUBE_URL", videoUrl);

在调用setResult()后,不应该前往onCreate()。您应该前往onActivityResult()


因此,参数VIDEO_URL的名称在两侧是相同的,我在这里犯了一个错误。那不是永远的烤箱。问题是一旦我收到请求,extras就为null。 - Alex Rashkov
onActivityResult() 被调用了吗?你尝试按照我建议的方式更改第二个 Activity 中的 Intent 了吗? - codeMagic
是的,不好。我的主活动肯定有问题,但我看不出来是什么问题。我可以将额外信息传递给SearchActivity,但无法传回主活动。在调试面板中,额外信息为空。 - Alex Rashkov

1

哦,我有什么地方错过了吗?在SearchActivity中,您使用“YOUTUBE_URL”键标识扩展数据,但在MainActivity中,您尝试使用“VIDEO_URL”键检索它。这两个键必须相同。

我为共享首选项、意图等类似于映射的结构定义键的方式在一个单独的类中进行定义,例如

public class Utils {

在那个类中,我使用以下内容来定义一个键:

public static final String KEY_VIDEO_URL = "com.example.myapp.KEY_VIDEO_URL";

在我的主要代码中,我这样引用关键字:
Intent incomingIntent = getResult();
String incomingURL = incomingIntent.getStringExtra(Utils.KEY_VIDEO_URL);
...

这有助于我避免一些错误。


因此,参数VIDEO_URL的名称在两侧是相同的,我在这里犯了一个错误。那不是永远的烤箱。问题是一旦我收到请求,extras就为null。 - Alex Rashkov

0

你可以尝试这个:

    Bundle extras;
    String url;
    public class MainActivity extends Activity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
            extras = getIntent().getExtras(); 

            btnSearch.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent search = new Intent(v.this, SearchActivity.class);
                    startActivityForResult(search, SEARCH_VIDEO_REQUEST);
                }
            });
        }

        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            if (requestCode == SEARCH_VIDEO_REQUEST) {
                if (resultCode == RESULT_OK) {


                      if (extras != null) {
                                  url = extras.getStringExtra("VIDEO_URL");

                                         }

                    if (url != null) {
                        txtUrl.setText(url);
                    }
                }
            }
        }
    }

0

我能够运行代码并进行了一些修正后得到了结果

修改

Intent search = new Intent(v.this, SearchActivity.class); 

在MainActivity中返回

Intent search = new Intent(MainActivity.this,SearchActivity.class);

并修改

Intent data = new Intent(SearchActivity.this, MainActivity.class);

在SearchActivity中返回

 Intent data =new Intent();

以下是完整代码。
public class MainActivity extends Activity {

    public static final int SEARCH_VIDEO_REQUEST = 1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        View btnSearch = findViewById(R.id.button1);
        btnSearch.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent search = new Intent(MainActivity.this,
                        SearchActivity.class);
                startActivityForResult(search, SEARCH_VIDEO_REQUEST);
            }
        });
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == SEARCH_VIDEO_REQUEST) {
            if (resultCode == RESULT_OK) {
                String url = data.getExtras().getString("VIDEO_URL");
                if (url != null) {
                    Toast.makeText(this, "url"+url, Toast.LENGTH_SHORT).show();
                    //txtUrl.setText(url);
                }
            }
        }
    }
}



public class SearchActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Button btnSend = new Button(this);
        setContentView(btnSend);

        btnSend.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                String videoUrl = "http://video-url.com";
                Intent data = new Intent();
                data.putExtra("VIDEO_URL", videoUrl);
                setResult(RESULT_OK, data);
                finish();
            }
        });
    }

}

0
在你的SearchActivity中,不要使用

Intent data = new Intent(SearchActivity.this, MainActivity.class);

使用空构造函数,例如:

Intent data = new Intent();

0

我认为问题与以下内容有关:

Intent(Context packageContext, Class cls) API级别1中添加

为特定组件创建意图。 所有其他字段(操作、数据、类型、类)均为空,但可以稍后使用显式调用进行修改。这提供了一种方便的方式来创建一个意图,该意图旨在执行硬编码的类名,而不是依赖系统为您找到适当的类;有关此操作的影响,请参见setComponent(ComponentName)。


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