我试图制作一个显示实时新闻的新闻应用程序,但出现空对象引用错误。
我的Main.java类:
private NewsAdapter mAdapter;
public final static String LOG_TAG = News.class.getName();
private TextView mEmptyStateTextView;
private static final int NEWS_LOADER_ID = 1;
private ProgressBar progressBar = null;
//Url for News
private static final String GardianNewws = "https://content.guardianapis.com/search?q=debate&tag=politics/politics&from-date=2019-01-01&api-key=62d26206-4f2a-42a2-8927-79de5746bd1d";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//fins a refreence to the(@link ListView)in the Layout
ListView NewsListView = (ListView)findViewById(R.id.list);
NewsListView.setEmptyView(mEmptyStateTextView);
//grab the progressbar
progressBar = (ProgressBar)findViewById(R.id.loading_spinner);
//create a new Adapter thet takes an empty list of earthquake
mAdapter = new NewsAdapter(this,new ArrayList<News>());
//set the adapter
NewsListView.setAdapter(mAdapter);
//set the item click listener on the ListView,which sends an intent
//to open a website with more information about the selected News
NewsListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//Find the Current News that was Clicked on
News currentNews = mAdapter.getItem(position);
//convert the String URL into a URL obj;
Uri newsUri = Uri.parse(currentNews.getUrl());
//create a new Intent to view the news URI
Intent websiteIntent = new Intent(Intent.ACTION_VIEW,newsUri);
//start the Intent
startActivity(websiteIntent);
}
});
}
}
我的新闻构造函数类:
//news serial
private String mSerial;
//main news title
private String mTitle;
//news feed
private String mNewsFeed;
//URL
private String mUrl;
public News(String serial,String title,String feed,String url){
mSerial = serial;
mTitle = title;
mNewsFeed = feed;
mUrl = url;
}
//get the News
public String getSerial(){
return mSerial;
}
public String getTitle(){
return mTitle;
}
public String getNewsFeed(){
return mNewsFeed;
}
public String getUrl(){
return mUrl;
}
我的NetworkAdapter.java类:
private static final String LOG_TAG = NewsAdapter.class.getSimpleName();
/**
* this is custom constructor (it does not mirror a superclass constructor );
* The context is used to inflate the layout file, and the list is the data we want
* to populate into the lists
* @param context The current context,Used to inflate the layout file
*
* @param News a list of words obj. to display in a list
*/
public NewsAdapter(Context context, ArrayList<News>news) {
super(context, 0,news);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View listItem = convertView;
if (listItem == null){
listItem = LayoutInflater.from(getContext()).inflate(R.layout.activity_main,parent,false);
}
//get the location of the obj.
News currentposition = getItem(position);
//find the textView
TextView title = (TextView)listItem.findViewById(R.id.title);
//set text on textView
title.setText(currentposition.getTitle());
//find the TextView
TextView MainNews = (TextView)listItem.findViewById(R.id.main_news);
//set the TextView
MainNews.setText(currentposition.getNewsFeed());
return listItem;
}
我的NewtorkUtils.java类:
/** Tag for the log messages */
public static final String LOG_TAG = NewsQueryUtils.class.getSimpleName();
/**
* Create a private constructor because no one should ever create a {@link NewsQueryUtils} object.
* This class is only meant to hold static variables and methods, which can be accessed
* directly from the class name NewsQueryUtils (and an object instance of QueryUtils is not needed).
*/
private NewsQueryUtils(){
}
//Query the News dataset and return an (@link Event) obj to represent an single earthquake
public static List<News> fetchNewsQueryData(String requestUrl){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.i(LOG_TAG,"Test fetchNewsData called...");
//create URL object
URL url = createUrl(requestUrl);
//perform HTTP request to the url and receive a JSON responce
String jsonResponce = null;
try {
jsonResponce = makeHTTPRequest(url);
} catch (IOException e){
Log.e(LOG_TAG,"Error closing input stream",e);
}
List<News>news = eatractFeatureFromJSON(jsonResponce);
//Return
return news;
}
/**
* Return new URL object from the given string URl
*/
private static URL createUrl(String stringUrl){
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Error with creating URL ", e);
return null;
}
return url;
}
//Make an HTTP request to the given url and return a string
private static String makeHTTPRequest(URL url) throws IOException{
String jsonResponce = "";
//if the URl is NULL, them retuen early
if (url == null){
return jsonResponce;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setConnectTimeout(10000/*millisecond*/);
urlConnection.setReadTimeout(10000/*millisecond*/);
urlConnection.setRequestMethod("GET");
urlConnection.connect();
//if the request was successful (Responce code 200),
//then read the input stream and parse the responce
if (urlConnection.getResponseCode() == 200){
inputStream = urlConnection.getInputStream();
jsonResponce = readFromStream(inputStream);
} else {
Log.e(LOG_TAG,"Error responce code" + urlConnection.getResponseCode());
}
}catch (IOException e){
Log.e(LOG_TAG,"Problem retrieving the earthquake JSON results.", e);
} finally {
if (urlConnection != null){
// Closing the input stream could throw an IOException, which is why
// the makeHttpRequest(URL url) method signature specifies than an IOException
// could be thrown.
inputStream.close();
}
}
return jsonResponce;
}
/**
* Convert the {@link InputStream} into a String which contains the
* whole JSON response from the server.
*/
private static String readFromStream(InputStream inputStream) throws IOException{
StringBuilder output = new StringBuilder();
if (inputStream != null){
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null){
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
/**
* Return a list of (@link News)obj. that has been built up from
* parsing a JSON responce
*/
private static List<News>eatractFeatureFromJSON(String newsJson){
//if the json string is empty or null,then return early
if (TextUtils.isEmpty(newsJson)){
return null;
}
//Create an empty Array
List<News>newss = new ArrayList<>();
try {
JSONObject baseJsonResponce = new JSONObject(newsJson);
JSONArray newsArray = baseJsonResponce.getJSONArray("response");
for (int i = 0;i<newsArray.length();i++){
JSONObject currentNews = newsArray.getJSONObject(i);
JSONObject properties = currentNews.getJSONObject("results");
String id = properties.getString("id");
String sectionId = properties.getString("sectionId");
String webttitle= properties.getString("webTitle");
// Extract the value for the key called "url"
String url = properties.getString("webUrl");
News news = new News(id,sectionId,webttitle,url);
newss.add(news);
}
} catch (JSONException e) {
e.printStackTrace();
}
return newss;
}
我的ListView.Xml类:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/list"
android:dividerHeight="1dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
<!-- empty text view -->
<TextView
android:id="@+id/emptyView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textAppearance="?android:textAppearanceMedium"
android:text="center"/>
<!-- progress view -->
<ProgressBar
android:id="@+id/loading_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
</RelativeLayout>
我的Activity_Main.xml类:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:paddingStart="16dp"
android:paddingLeft="16dp"
android:paddingEnd="16dp"
android:paddingRight="16dp"
tools:context=".MainActivity">
<TextView
android:id="@+id/serial"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:fontFamily="sans-serif"
android:gravity="center"
android:textColor="@android:color/black"
android:textSize="16dp"
android:tooltipText="1" />
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:ellipsize="end"
android:fontFamily="sans-serif"
android:maxLines="1"
android:textAllCaps="true"
android:textColor="@color/colorPrimary"
android:textSize="12dp"
android:tooltipText="Heading" />
<TextView
android:id="@+id/main_news"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:textSize="12dp"
android:tooltipText="here" />
</LinearLayout>
</LinearLayout>
我的错误:
Caused by: java.lang.NullPointerException:
Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)'
on a null object reference at com.example.user.worldnews.MainActivity.onCreate(MainActivity.java:46)
答案 0 :(得分:0)
以下错误:
Caused by: java.lang.NullPointerException:
Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)'
on a null object reference at com.example.user.worldnews.MainActivity.onCreate(MainActivity.java:46)
是因为您的activity_main.xml
中没有ListView。
将以下ListView添加到您的xml中:
<ListView
android:id="@+id/list"
android:dividerHeight="1dp"
android:layout_width="match_parent"
android:layout_height="match_parent"/>