启动画面导致 Main Activity 中的空指针与 AsyncTask
Splash Screen causes null pointer in Main Activity with AsyncTask
我正在尝试向我的 Android Rss Reader 应用程序添加启动画面,以便我可以检查网络连接并确定用户首先看到哪个屏幕,具体取决于连接情况。
没有 SplashScreen,MainActivity.java 工作正常,但是当我将 SplashScreenActivity 设置为 Manifest 中的启动器时,MainActivity 中的 Asynctask 在运行时抛出空指针。有人知道这可能是什么原因吗?
感谢您的宝贵时间!
SplashScreenActivity.java
enter code here
public class SplashScreenActivity extends MainActivity {
boolean alreadyExecuted = false;
private static String TAG = SplashScreenActivity.class.getName();
private static long SLEEP_TIME = 5;
@Override
public void onCreate(Bundle savedInstanceState) {
this.requestWindowFeature(Window.FEATURE_NO_TITLE); // Removes title bar
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // Removes notification bar
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen);
// Start timer and launch main activity
IntentLauncher launcher = new IntentLauncher();
launcher.start();
}
private class IntentLauncher extends Thread {
@Override
/**
* Sleep for some time and than start new activity.
*/
public void run() {
try {
// Sleeping
Thread.sleep(SLEEP_TIME*2000);
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
//If this method is called once, set boolean alreadyExecuted to true
if(!alreadyExecuted)
{
Check();
alreadyExecuted=true;
}
}
}
//Check if network is available. If so go to MainActivity screen, which requires internet
//If not, go to MyFeeds screen
public void Check()
{
if (NetworkCheck.getInstance(this).isOnline()) {
Intent intent = new Intent(SplashScreenActivity.this, MainActivity.class);
SplashScreenActivity.this.startActivity(intent);
SplashScreenActivity.this.finish();
}
else
{
Intent intent = new Intent(SplashScreenActivity.this, MyFeedsScreen.class);
SplashScreenActivity.this.startActivity(intent);
SplashScreenActivity.this.finish();
}
}}
MainActivity.java
public class MainActivity extends Activity {
private MainActivity local;
private DatabaseHandler db;
//Method to create main application view
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//set view
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
//**************************create a button to move to the user's saved feeds screen*****************************
Button myFeedsButton = (Button) findViewById(R.id.myFeedsButton);
myFeedsButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
startActivity(new Intent(MainActivity.this, MyFeedsScreen.class));
}
});
//*****************************************************************************************************************
//Create new instance of database handler
db = new DatabaseHandler(this);
//set local ref to this activity
local = this;
//Calls the doInBackground method
GetRSSDataTask task = new GetRSSDataTask();
//start download Rss task - execute method calls the
task.execute("http://pitchfork.com/rss/reviews/best/albums/");
//debug thread name
Log.d("RssReaderApp", Thread.currentThread().getName());
}
//*******************************************************************************************************************
private class GetRSSDataTask extends AsyncTask<String, Void, List<RssItem>>
{
@Override
protected List<RssItem> doInBackground(String... urls) {
//debug task thread name
Log.d("RssReaderApp", Thread.currentThread().getName());
try {
//create a new reader
RssReader rssReader = new RssReader(urls[0]);
//Parse RSS, get items
return rssReader.getItems();
} catch (Exception e) {
Log.e("RssReaderApp", e.getMessage());
}
return null;
}//doInBackground
//is invoked on UI thread after background tasks are complete.
// Results of background task are passed here as a parameter
@Override
protected void onPostExecute(List<RssItem> result)
{
//Gets listview from main.xml
final ListView listItems = (ListView) findViewById(R.id.listMainView);
//Creates a new list adapter - displays an array of strings in listview
ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(local, android.R.layout.simple_list_item_1, result);
//Set list adapter for listView
listItems.setAdapter(adapter);
//OnItemClick listener set to allow user to access content from title
listItems.setOnItemClickListener(new ListListener(result, local));
//*******************************LONG CLICK FUNCTIONALITY******************************************
//Set new long click listener which should allow item to be stored to db
listItems.setLongClickable(true);
listItems.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
try {
db.open();
RssItem fromList = (RssItem) listItems.getItemAtPosition(position);
RssItem item = new RssItem();
item.title = fromList.title;
item._id = fromList._id;
//item.completeTextLink = fromList.completeTextLink;
//item.mainBody = fromList.mainBody;
item.link = fromList.link;
item.description = fromList.description;
// item.page = fromList.page;
db.insertRssItem(item);
db.close();
} catch (SQLException e) {
e.printStackTrace();
}
Toast.makeText(getBaseContext(), "Item saved in My Feeds!", Toast.LENGTH_SHORT).show();
return true;
}
});
}//onPostExecute
}//getRssTaskClass}//class
Android 清单,带有 SplashScreenActvity,而不是 MainActivity 现在设置为启动器:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:label="@string/app_name">
<activity android:name="com.example.rory.RssReaderApp.MainActivity">
</activity>
<activity android:name="com.example.rory.RssReaderApp.MyFeedsScreen"></activity>
<activity android:name=".DetailsActivity"></activity>
<activity android:name="com.example.rory.RssReaderApp.SplashScreenActivity">
android:icon="@drawable/newspaper"
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>
LogCat 错误:
08-19 02:23:52.467 15372-15372/com.example.rory.readerapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.rory.readerapp, PID: 15372
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at com.example.rory.RssReaderApp.MainActivity$GetRSSDataTask.onPostExecute(MainActivity.java:113)
at com.example.rory.RssReaderApp.MainActivity$GetRSSDataTask.onPostExecute(MainActivity.java:79)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access0(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5312)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)
在设置 listItems
时尝试在 onPostExecute
中引用 MainActivity。
final ListView listItems = (ListView) local.findViewById(R.id.listMainView);
问题解决了!我不小心让 SplashScreenActivity.java class 扩展了 MainActivity 而不是 Activity。
感谢大家的帮助!
我正在尝试向我的 Android Rss Reader 应用程序添加启动画面,以便我可以检查网络连接并确定用户首先看到哪个屏幕,具体取决于连接情况。
没有 SplashScreen,MainActivity.java 工作正常,但是当我将 SplashScreenActivity 设置为 Manifest 中的启动器时,MainActivity 中的 Asynctask 在运行时抛出空指针。有人知道这可能是什么原因吗?
感谢您的宝贵时间!
SplashScreenActivity.java
enter code here
public class SplashScreenActivity extends MainActivity {
boolean alreadyExecuted = false;
private static String TAG = SplashScreenActivity.class.getName();
private static long SLEEP_TIME = 5;
@Override
public void onCreate(Bundle savedInstanceState) {
this.requestWindowFeature(Window.FEATURE_NO_TITLE); // Removes title bar
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // Removes notification bar
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen);
// Start timer and launch main activity
IntentLauncher launcher = new IntentLauncher();
launcher.start();
}
private class IntentLauncher extends Thread {
@Override
/**
* Sleep for some time and than start new activity.
*/
public void run() {
try {
// Sleeping
Thread.sleep(SLEEP_TIME*2000);
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
//If this method is called once, set boolean alreadyExecuted to true
if(!alreadyExecuted)
{
Check();
alreadyExecuted=true;
}
}
}
//Check if network is available. If so go to MainActivity screen, which requires internet
//If not, go to MyFeeds screen
public void Check()
{
if (NetworkCheck.getInstance(this).isOnline()) {
Intent intent = new Intent(SplashScreenActivity.this, MainActivity.class);
SplashScreenActivity.this.startActivity(intent);
SplashScreenActivity.this.finish();
}
else
{
Intent intent = new Intent(SplashScreenActivity.this, MyFeedsScreen.class);
SplashScreenActivity.this.startActivity(intent);
SplashScreenActivity.this.finish();
}
}}
MainActivity.java
public class MainActivity extends Activity {
private MainActivity local;
private DatabaseHandler db;
//Method to create main application view
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//set view
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
//**************************create a button to move to the user's saved feeds screen*****************************
Button myFeedsButton = (Button) findViewById(R.id.myFeedsButton);
myFeedsButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
startActivity(new Intent(MainActivity.this, MyFeedsScreen.class));
}
});
//*****************************************************************************************************************
//Create new instance of database handler
db = new DatabaseHandler(this);
//set local ref to this activity
local = this;
//Calls the doInBackground method
GetRSSDataTask task = new GetRSSDataTask();
//start download Rss task - execute method calls the
task.execute("http://pitchfork.com/rss/reviews/best/albums/");
//debug thread name
Log.d("RssReaderApp", Thread.currentThread().getName());
}
//*******************************************************************************************************************
private class GetRSSDataTask extends AsyncTask<String, Void, List<RssItem>>
{
@Override
protected List<RssItem> doInBackground(String... urls) {
//debug task thread name
Log.d("RssReaderApp", Thread.currentThread().getName());
try {
//create a new reader
RssReader rssReader = new RssReader(urls[0]);
//Parse RSS, get items
return rssReader.getItems();
} catch (Exception e) {
Log.e("RssReaderApp", e.getMessage());
}
return null;
}//doInBackground
//is invoked on UI thread after background tasks are complete.
// Results of background task are passed here as a parameter
@Override
protected void onPostExecute(List<RssItem> result)
{
//Gets listview from main.xml
final ListView listItems = (ListView) findViewById(R.id.listMainView);
//Creates a new list adapter - displays an array of strings in listview
ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(local, android.R.layout.simple_list_item_1, result);
//Set list adapter for listView
listItems.setAdapter(adapter);
//OnItemClick listener set to allow user to access content from title
listItems.setOnItemClickListener(new ListListener(result, local));
//*******************************LONG CLICK FUNCTIONALITY******************************************
//Set new long click listener which should allow item to be stored to db
listItems.setLongClickable(true);
listItems.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
try {
db.open();
RssItem fromList = (RssItem) listItems.getItemAtPosition(position);
RssItem item = new RssItem();
item.title = fromList.title;
item._id = fromList._id;
//item.completeTextLink = fromList.completeTextLink;
//item.mainBody = fromList.mainBody;
item.link = fromList.link;
item.description = fromList.description;
// item.page = fromList.page;
db.insertRssItem(item);
db.close();
} catch (SQLException e) {
e.printStackTrace();
}
Toast.makeText(getBaseContext(), "Item saved in My Feeds!", Toast.LENGTH_SHORT).show();
return true;
}
});
}//onPostExecute
}//getRssTaskClass}//class
Android 清单,带有 SplashScreenActvity,而不是 MainActivity 现在设置为启动器:
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:label="@string/app_name">
<activity android:name="com.example.rory.RssReaderApp.MainActivity">
</activity>
<activity android:name="com.example.rory.RssReaderApp.MyFeedsScreen"></activity>
<activity android:name=".DetailsActivity"></activity>
<activity android:name="com.example.rory.RssReaderApp.SplashScreenActivity">
android:icon="@drawable/newspaper"
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>
LogCat 错误:
08-19 02:23:52.467 15372-15372/com.example.rory.readerapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.rory.readerapp, PID: 15372
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at com.example.rory.RssReaderApp.MainActivity$GetRSSDataTask.onPostExecute(MainActivity.java:113)
at com.example.rory.RssReaderApp.MainActivity$GetRSSDataTask.onPostExecute(MainActivity.java:79)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access0(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5312)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)
在设置 listItems
时尝试在 onPostExecute
中引用 MainActivity。
final ListView listItems = (ListView) local.findViewById(R.id.listMainView);
问题解决了!我不小心让 SplashScreenActivity.java class 扩展了 MainActivity 而不是 Activity。
感谢大家的帮助!