我一直在搞乱这段代码:
package com.example.doblevxv5.sunny;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Encapsulates fetching the forecast and displaying it as a {@link ListView} layout.
*/
public class ForecastFragment extends Fragment {
public ForecastFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Add this line in order for this fragment to handle menu events.
setHasOptionsMenu(true);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.forecastfragment, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_refresh) {
FetchWeatherTask weatherTask = new FetchWeatherTask();
weatherTask.execute();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Create some dummy data for the ListView. Here's a sample weekly forecast
String[] data = {
"Mon 6/23 - Sunny - 31/17",
"Tue 6/24 - Foggy - 21/8",
"Wed 6/25 - Cloudy - 22/17",
"Thurs 6/26 - Rainy - 18/11",
"Fri 6/27 - Foggy - 21/10",
"Sat 6/28 - TRAPPED IN WEATHERSTATION - 23/18",
"Sun 6/29 - Sunny - 20/7"
};
List<String> weekForecast = new ArrayList<String>(Arrays.asList(data));
// Now that we have some dummy forecast data, create an ArrayAdapter.
// The ArrayAdapter will take data from a source (like our dummy forecast) and
// use it to populate the ListView it's attached to.
ArrayAdapter<String> forecastAdapter =
new ArrayAdapter<String>(
getActivity(), // The current context (this activity)
R.layout.list_item_forecast, // The name of the layout ID.
R.id.list_item_forecast_textview, // The ID of the textview to populate.
weekForecast);
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
// Get a reference to the ListView, and attach this adapter to it.
ListView listView = (ListView) rootView.findViewById(R.id.listview_forecast);
listView.setAdapter(forecastAdapter);
return rootView;
}
public class FetchWeatherTask extends AsyncTask<Void, Void, Void> {
private final String LOG_TAG = FetchWeatherTask.class.getSimpleName();
@Override
protected Void doInBackground(Void... params) {
// These two need to be declared outside the try/catch
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String forecastJsonStr = null;
try {
// Construct the URL for the OpenWeatherMap query
// Possible parameters are avaiable at OWM's forecast API page, at
// http://openweathermap.org/API#forecast
URL url = new URL("http://api.openweathermap.org/data/2.5/forecast/daily?q=94043&mode=json&units=metric&cnt=7");
// Create the request to OpenWeatherMap, and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
forecastJsonStr = buffer.toString();
} catch (IOException e) {
Log.e(LOG_TAG, "Error ", e);
// If the code didn't successfully get the weather data, there's no point in attemping
// to parse it.
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e(LOG_TAG, "Error closing stream", e);
}
}
}
return null;
}
}
}
此代码来自以下GIS Hub,来自oline Android课程: https://github.com/udacity/Sunshine/blob/2.05-trigger-refresh/app/src/main/java/com/example/android/sunshine/app/ForecastFragment.java
以下是Logcat显示的内容:
11-10 00:03:41.479 13081-13081/com.example.doblevxv5.sunny E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.doblevxv5.sunny/com.example.doblevxv5.sunny.ForecastFragment}: java.lang.ClassCastException: com.example.doblevxv5.sunny.ForecastFragment cannot be cast to android.app.Activity
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2016)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2117)
at android.app.ActivityThread.access$700(ActivityThread.java:134)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1218)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4867)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassCastException: com.example.doblevxv5.sunny.ForecastFragment cannot be cast to android.app.Activity
at android.app.Instrumentation.newActivity(Instrumentation.java:1068)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2007)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2117)
at android.app.ActivityThread.access$700(ActivityThread.java:134)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1218)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4867)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
at dalvik.system.NativeStart.main(Native Method)
以下是AndroidManifest.xml
文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.doblevxv5.sunny" >
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:debuggable="true">
<activity
android:name=".ForecastFragment"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
当我在手机中运行应用程序时,它就会停止。我甚至无法打开应用程序。
感谢您的帮助!
答案 0 :(得分:1)
你的日志清楚地说了
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.doblevxv5.sunny/com.example.doblevxv5.sunny.ForecastFragment}: java.lang.ClassCastException: com.example.doblevxv5.sunny.ForecastFragment cannot be cast to android.app.Activity
ForcastFragment
不是Activity
它是Fragment
而您无法在manifest.xml
上注册
因此,最好在运行时创建一个Activity
并选择一个FrameLayout
并在ForcastFragment
加载Activity
,并在manifest.xml.
中注册您的活动}
答案 1 :(得分:1)
您无法在Fragment
中声明manifest
。在清单中删除android:name=".ForecastFragment"
并代替ForecaseFragment
指定您的Activity
名称。
答案 2 :(得分:1)
替换它:
android:name=".ForecastFragment"
有了这个:
android:name=".MainActivity"
注意:只在AndroidManifest.xml中注册活动,无需注册Fragment,Fragment是活动的一部分,因此可以直接调用AndroidManifext.xml中没有注册的活动
答案 3 :(得分:0)
这里发生的是您尝试将片段实例化为活动。
您的类ForecastFragment是代码所声明的片段的扩展。片段构成活动布局的一部分,因此它必须是活动的一部分,以便可以将其实例化为视图。
查看他们在课程中提供的主要活动 - https://github.com/udacity/Sunshine/blob/2.05-trigger-refresh/app/src/main/java/com/example/android/sunshine/app/MainActivity.java
答案 4 :(得分:0)
请参阅以下链接,其中显示了如何创建和执行片段并在清单中提及活动
答案 5 :(得分:0)
您应该关注错误的这一行:
Caused by: java.lang.ClassCastException: com.example.doblevxv5.sunny.ForecastFragment cannot be cast to android.app.Activity
at android.app.Instrumentation.newActivity(Instrumentation.java:1068)
您的课程是片段,而不是活动。尝试使用:
public class ForecastFragment extends FragmentActivity{
...
}
在您提供的链接上,有多个活动,您只选择了一个.java文件,还有另一个名为MainActivity的.java文件。 https://github.com/udacity/Sunshine/blob/2.05-trigger-refresh/app/src/main/java/com/example/android/sunshine/app/MainActivity.java 您应该了解Android的工作原理:http://developer.android.com/training/basics/activity-lifecycle/index.html 您的应用程序基于活动,将活动视为本书的页面,将主活动视为本书的第一页,并将片段视为该书的内容。