【问题标题】:How to start Activity from Fragment? Android如何从 Fragment 启动 Activity?安卓
【发布时间】:2014-03-17 23:51:20
【问题描述】:

我是 Android 应用开发的新手。我使用这个带有片段的开源滑动菜单:http://www.androidhive.info/2013/11/android-sliding-menu-using-navigation-drawer/

我想在滑动菜单项目中实现这个 rss feed 解析器(AndroidRssReader,也是开源的):http://android-er.blogspot.in/2010/04/simple-rss-reader-using-androids.html

我的想法是,滑动菜单项之一(一个片段)启动 AndroidRssReader.java 活动。我将 AndroidRssReader.java 文件放在我的 /src/stiw47.logos 中,并想从 RssFragment.java 调用 em。这是我的 RssFragment.java 的源代码:

public class RssFragment extends Fragment {

    public RssFragment (){

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_rss, container, false);

        Button newPage = (Button)v.findViewById(R.id.bNovosti);
        newPage.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getActivity(), AndroidRssReader.class);
                startActivity(intent);
            }
        });
        return v;
    }
}

当我单击按钮调用 AndroidRssReader 类时,我被强制关闭。

这是我的 adb logcat:

    I/ActivityManager(13216): Timeline: Activity_launch_request id:stiw47.logos time:7317484
    V/AudioPolicyManagerBase( 1678): getOutput() stream 1, samplingRate 0, format0,         channelMask 3, flags 0
V/AudioPolicyManagerBase( 1678): getOutput() returns output 2
V/audio_policy_anm( 1678): audio_io_handle_t android::ap_get_output(audio_policy*, audio_stream_type_t, uint32_t, audio_format_t, uint32_t, audio_output_flags_t): tid 1678
V/AudioPolicyManagerBase( 1678): getOutput() stream 1, samplingRate 0, format 0, channelMask 3, flags 0
V/AudioPolicyManagerBase( 1678): getOutput() returns output 2
V/audio_policy_anm( 1678): audio_io_handle_t android::ap_get_output(audio_policy*, audio_stream_type_t, uint32_t, audio_format_t, uint32_t, audio_output_flags_t): tid 2371
V/AudioPolicyManagerBase( 1678): getOutput() stream 1, samplingRate 48000, format 1, channelMask 3, flags 4
V/AudioPolicyManagerBase( 1678): getOutput() returns output 2
W/AudioTrack( 2143): AUDIO_OUTPUT_FLAG_FAST denied by client due to mismatching sample rate (48000 vs 44100)
I/ActivityManager( 2143): START u0 {cmp=stiw47.logos/.AndroidRssReader} from pid 13216
V/AudioPolicyManagerBase( 1678): startOutput() output 2, stream 1, session 62
V/AudioPolicyManagerBase( 1678): changeRefCount() stream 1, count 1
V/AudioPolicyManagerBase( 1678): getNewDevice() selected device 2
V/AudioPolicyManagerBase( 1678): setOutputDevice() output 2 device 0002 force 0 delayMs 0 
V/AudioPolicyManagerBase( 1678): setOutputDevice() prevDevice 0002
V/AudioPolicyManagerBase( 1678): setOutputDevice() setting same device 0002 or null device for output 2
V/AudioPolicyManagerBase( 1678): releaseOutput() 2
D/AndroidRuntime(13216): Shutting down VM
W/dalvikvm(13216): threadid=1: thread exiting with uncaught exception (group=0x41febce0)
E/AndroidRuntime(13216): FATAL EXCEPTION: main
E/AndroidRuntime(13216): Process: stiw47.logos, PID: 13216
E/AndroidRuntime(13216): java.lang.RuntimeException: Unable to start activity ComponentInfo{stiw47.logos/stiw47.logos.AndroidRssReader}: android.os.NetworkOnMainThreadException
E/AndroidRuntime(13216):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2215)
E/AndroidRuntime(13216):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2265)
E/AndroidRuntime(13216):    at android.app.ActivityThread.access$800(ActivityThread.java:145)
E/AndroidRuntime(13216):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1206)
E/AndroidRuntime(13216):    at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime(13216):    at android.os.Looper.loop(Looper.java:136)
E/AndroidRuntime(13216):    at android.app.ActivityThread.main(ActivityThread.java:5081)
E/AndroidRuntime(13216):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(13216):    at java.lang.reflect.Method.invoke(Method.java:515)
E/AndroidRuntime(13216):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
E/AndroidRuntime(13216):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607)
E/AndroidRuntime(13216):    at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(13216): Caused by: android.os.NetworkOnMainThreadException
E/AndroidRuntime(13216):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1145)
E/AndroidRuntime(13216):    at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
E/AndroidRuntime(13216):    at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
E/AndroidRuntime(13216):    at java.net.InetAddress.getAllByName(InetAddress.java:214)
E/AndroidRuntime(13216):    at com.android.okhttp.internal.Dns$1.getAllByName(Dns.java:28)
E/AndroidRuntime(13216):    at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:216)
E/AndroidRuntime(13216):    at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:122)
E/AndroidRuntime(13216):    at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:292)
E/AndroidRuntime(13216):    at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
E/AndroidRuntime(13216):    at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
E/AndroidRuntime(13216):    at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)
E/AndroidRuntime(13216):    at com.android.okhttp.internal.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:296)
E/AndroidRuntime(13216):    at com.android.okhttp.internal.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:179)
E/AndroidRuntime(13216):    at java.net.URL.openStream(URL.java:470)
E/AndroidRuntime(13216):    at stiw47.logos.AndroidRssReader.onCreate(AndroidRssReader.java:41)
E/AndroidRuntime(13216):    at android.app.Activity.performCreate(Activity.java:5231)
E/AndroidRuntime(13216):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
E/AndroidRuntime(13216):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2169)
E/AndroidRuntime(13216):    ... 11 more
W/ActivityManager( 2143):   Force finishing activity stiw47.logos/.AndroidRssReader
W/ActivityManager( 2143):   Force finishing activity stiw47.logos/.MainActivity

注意 1:我在 Manifest 中声明了一项活动并设置了 Internet 权限 注意 2:当我将 AndroidRssReader.java 类编译为“独立”应用程序时,它正在工作,但是当我尝试在“我的应用程序”中运行 AndroidRssReader.java 类时它崩溃了。

我哪里错了?

【问题讨论】:

  • 这就是您开始活动的方式。您在 Activity 中收到 NetworkOnMainThread 异常,这意味着您正在 UI 线程上进行网络调用。您的活动在开始之前就崩溃了。
  • @stiw47 :检查我的答案如下

标签: android eclipse fragment forceclose rss-reader


【解决方案1】:

您犯的错误是您的代码中有某处(完全在类中 AndroidRssReader.java Line 41)。您在 MainThread (UIThread) 中执行了网络调用或 http 请求。您应该将该代码放在 [AsyncTask][1] 中。

查看tutorial 了解如何在 Android 中使用 AsyncTask

编辑:

onCreate() 方法中检索 xml 并解析它的代码应该在 AsyncTask 中,如下所示:

new AsyncTask<Void, Void, String>() {

            @Override
            protected String doInBackground(Void... params) {

                String result = "Cannot connect RSS!";
                try {
                      URL rssUrl = new URL("http://feeds.feedburner.com/Android-er?format=xml");
                      SAXParserFactory mySAXParserFactory = SAXParserFactory.newInstance();
                      SAXParser mySAXParser = mySAXParserFactory.newSAXParser();
                      XMLReader myXMLReader = mySAXParser.getXMLReader();
                      RSSHandler myRSSHandler = new RSSHandler();
                      myXMLReader.setContentHandler(myRSSHandler);
                      InputSource myInputSource = new InputSource(rssUrl.openStream());
                      myXMLReader.parse(myInputSource);

                      result = streamTitle;

                     } catch (MalformedURLException e) {
                      e.printStackTrace();
                     } catch (ParserConfigurationException e) {
                      e.printStackTrace();
                     } catch (SAXException e) {
                      e.printStackTrace();
                     } catch (IOException e) {
                      e.printStackTrace();
                     }
                return result;
            }

            @Override
            protected void onPostExecute(String response) {
                if(response != null) {
                    result.setText(response);
                }
            }
        }.execute();

【讨论】:

  • 谢谢你们,你们两个(Houcine 和 nKn),现在正在工作。我的问题解决了。
【解决方案2】:

最重要的一行是这一行:

E/AndroidRuntime(13216): java.lang.RuntimeException: Unable to start activity ComponentInfo{stiw47.logos/stiw47.logos.AndroidRssReader}: android.os.NetworkOnMainThreadException

问题不在于启动您的Activity,问题在于这个Activity 正在主UI 线程中执行网络操作。 Android 禁止这样做,因为这样做您不允许用户与您的应用交互,从而导致 ANR(这将使用户体验很差,他们可能不会再使用您的应用了)。

只需将网络代码放在AsyncTask 中。欲了解更多信息,请查看here

【讨论】:

  • 对不起,我是一个非常非常新手。我应该将哪部分代码准确地放入 AsyncTask 中(此处提供了 AndroidRssReader.java 代码:android-er.blogspot.in/2010/04/…)?提前谢谢。
  • 谢谢你们,你们两个(Houcine 和 nKn),现在正在工作。我的问题解决了。
猜你喜欢
  • 2016-12-19
  • 2015-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-20
  • 2012-02-03
  • 1970-01-01
相关资源
最近更新 更多