the activity crashes when I try and set any imageview image (either setImageBitmap or setImageView) it does this anywhere but in the one getview.
I am trying to get an imageview array that I can use in my adapter for my gridview (problem marked "problem here")
package joshpike.hsh.hsh_game;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
public class DisplayActivity extends MainActivity
{
int screenTileWidth = 3;
int nativeTileSize = 256;
int tileSize;
int numberColumn;
int numberRow;
int floorNum;
ImageView[][] topGridArray = null;
ImageView[][] bottomGridArray = null;
//sets tilesize, numberColumn and numberRow
#SuppressLint("NewApi")
public void setGridVars()
{
//set tileSize
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
int screenWidth;
if (android.os.Build.VERSION.SDK_INT >= 13)
{
display.getSize(size);
screenWidth = size.x;
}
else
{
screenWidth = display.getWidth();
}
tileSize = screenWidth / screenTileWidth;
//set numberColumn and numberRow
try
{
String dataFilePath = "floors/" + floorNum + "/FloorData.txt";
InputStream dataInputStream = getAssets().open(dataFilePath);
BufferedReader reader = new BufferedReader(new InputStreamReader(dataInputStream));
String line = reader.readLine();
line = reader.readLine();
numberColumn = Integer.parseInt(line);
line = reader.readLine();
numberRow = Integer.parseInt(line);
dataInputStream.close();
}
catch (IOException e)
{
System.out.println("exception found in try/catch in DisplayActivity.setGridVars method");
}
for(int x = 0; x < numberColumn ; x++ )
{
for(int y = 0; y < numberRow ; y++ )
{
///***PROBLEM HERE***///
bottomGridArray[x][y].setImageBitmap(currentImageView("bottom", x, y));
topGridArray[x][y].setImageBitmap(currentImageView("top", x, y));
}
}
}
//returns the one imageView for gridViewForadapter
public Bitmap currentImageView(String layer, int X, int Y )
{
try
{
Bitmap returnBitmap = null;
String imgDirectory = "floors/" + floorNum + "/" + layer + "/" + X + "," + Y + ".png";
InputStream imageInputStream = getAssets().open(imgDirectory);
returnBitmap = BitmapFactory.decodeStream(imageInputStream);
imageInputStream.close();
return returnBitmap;
}
catch (IOException e)
{
System.out.println("exception found in try/catch in DisplayActivity.currentImageView method");
return null;
}
}
public int returnGridCord (int position, char whatCord)
{
position = position + 1;
float rowFromTop = (float) position / numberColumn;
if (rowFromTop != Math.round(rowFromTop))
{
rowFromTop = ((float) Math.ceil( rowFromTop));
}
int returnY = Math.abs( (int)rowFromTop - numberRow);
int returnX = (position - ( ( (int)rowFromTop -1 ) * numberColumn) ) - 1;
System.out.println(position + ":" + returnX + "x" + returnY);
if (whatCord == 'X')
{
return returnX;
}
else
{
return returnY;
}
}
public class ImageAdapter extends BaseAdapter
{
private Context mContext;
// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent)
{
ImageView imageView;
if (convertView == null)
{
// if it's not recycled, initialize some attributes
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(tileSize, tileSize));
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(0, 0, 0, 0);
}
else
{
imageView = (ImageView) convertView;
}
System.out.println("endish of getview");
imageView.setImageResource(R.drawable.ic_launcher);
return imageView;
}
public ImageAdapter(Context c)
{
mContext = c;
}
#Override
public int getCount()
{
return numberColumn * numberRow;
}
#Override
public Object getItem(int position)
{
return null;
}
#Override
public long getItemId(int position)
{
return 0;
}
}
// Inflate the menu; this adds items to the action bar if it is present.
//makes the options menu
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.display, menu);
return true;
}
//what happens if you select items from the options menu
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId() )
{
case R.id.miniMap:
return true;
}
return super.onOptionsItemSelected(item);
}
//called when activity is started for first time either for first time or after destoryed
#Override
protected void onCreate(Bundle savedInstanceState)
{
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.display);
setGridVars();
System.out.println("DisplayActivity test about to start");
//ImageAdapter test = null;
//returnGridCord(0,"X");
GridView bottomMapGrid = (GridView)findViewById(R.id.bottomMapGrid);
bottomMapGrid.setNumColumns(numberColumn);
bottomMapGrid.setColumnWidth( tileSize );
bottomMapGrid.setStretchMode( GridView.NO_STRETCH ) ;
bottomMapGrid.setAdapter(new ImageAdapter(this));
System.out.println("DisplayActivity onCreate done");
}
//called when Activity goes from paused to active
#Override
protected void onResume()
{
super.onResume();
System.out.println("DisplayActivity onResume done");
}
//called when Activity goes from active to paused
#Override
protected void onPause()
{
super.onPause();
System.out.println("DisplayActivity onPause done");
}
//called when Activity goes from paused to stopped
#Override
protected void onStop()
{
super.onStop();
System.out.println("DisplayActivity onStop done");
}
//called when Activity goes from stopped to destroyed
#Override
protected void onDestroy()
{
super.onDestroy();
System.out.println("DisplayActivity onDestroy done");
}
//called when Activity has been stopped, is going to be paused then active
#Override
protected void onRestart()
{
super.onRestart();
System.out.println("DisplayActivity onRestart done");
}
//called when Activity is transitioning to paused either for first time or after it has been stopped
#Override
protected void onStart()
{
super.onStart();
System.out.println("DisplayActivity onStart done");
}
}
logcat:
03-20 17:16:43.437: I/System.out(22850): MainActivity onCreate done
03-20 17:16:43.437: I/System.out(22850): MainActivity onStart done
03-20 17:16:43.437: I/System.out(22850): MainActivity onResume done
03-20 17:16:43.848: D/TextLayoutCache(22850): Using debug level: 0 - Debug Enabled: 0
03-20 17:16:44.088: D/libEGL(22850): loaded /system/lib/egl/libGLES_android.so
03-20 17:16:44.168: D/libEGL(22850): loaded /system/lib/egl/libEGL_mali.so
03-20 17:16:44.208: D/libEGL(22850): loaded /system/lib/egl/libGLESv1_CM_mali.so
03-20 17:16:44.218: D/libEGL(22850): loaded /system/lib/egl/libGLESv2_mali.so
03-20 17:16:44.358: D/OpenGLRenderer(22850): Enabling debug mode 0
03-20 17:16:48.973: I/System.out(22850): MainActivity onPause done
03-20 17:16:49.974: D/OpenGLRenderer(22850): Flushing caches (mode 0)
03-20 17:16:50.674: I/System.out(22850): MainActivity onCreate done
03-20 17:16:50.915: D/AndroidRuntime(22850): Shutting down VM
03-20 17:16:50.915: W/dalvikvm(22850): threadid=1: thread exiting with uncaught exception (group=0x40aa8210)
03-20 17:16:51.005: E/AndroidRuntime(22850): FATAL EXCEPTION: main
03-20 17:16:51.005: E/AndroidRuntime(22850): java.lang.RuntimeException: Unable to start activity ComponentInfo{joshpike.hsh.hsh_game/joshpike.hsh.hsh_game.DisplayActivity}: java.lang.NullPointerException
03-20 17:16:51.005: E/AndroidRuntime(22850): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1967)
03-20 17:16:51.005: E/AndroidRuntime(22850): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
03-20 17:16:51.005: E/AndroidRuntime(22850): at android.app.ActivityThread.access$600(ActivityThread.java:127)
03-20 17:16:51.005: E/AndroidRuntime(22850): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158)
03-20 17:16:51.005: E/AndroidRuntime(22850): at android.os.Handler.dispatchMessage(Handler.java:99)
03-20 17:16:51.005: E/AndroidRuntime(22850): at android.os.Looper.loop(Looper.java:137)
03-20 17:16:51.005: E/AndroidRuntime(22850): at android.app.ActivityThread.main(ActivityThread.java:4448)
03-20 17:16:51.005: E/AndroidRuntime(22850): at java.lang.reflect.Method.invokeNative(Native Method)
03-20 17:16:51.005: E/AndroidRuntime(22850): at java.lang.reflect.Method.invoke(Method.java:511)
03-20 17:16:51.005: E/AndroidRuntime(22850): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:823)
03-20 17:16:51.005: E/AndroidRuntime(22850): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:590)
03-20 17:16:51.005: E/AndroidRuntime(22850): at dalvik.system.NativeStart.main(Native Method)
03-20 17:16:51.005: E/AndroidRuntime(22850): Caused by: java.lang.NullPointerException
03-20 17:16:51.005: E/AndroidRuntime(22850): at joshpike.hsh.hsh_game.DisplayActivity.setGridVars(DisplayActivity.java:85)
03-20 17:16:51.005: E/AndroidRuntime(22850): at joshpike.hsh.hsh_game.DisplayActivity.onCreate(DisplayActivity.java:235)
03-20 17:16:51.005: E/AndroidRuntime(22850): at android.app.Activity.performCreate(Activity.java:4465)
03-20 17:16:51.005: E/AndroidRuntime(22850): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
03-20 17:16:51.005: E/AndroidRuntime(22850): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1931)
03-20 17:16:51.005: E/AndroidRuntime(22850): ... 11 more
03-20 17:16:56.510: I/Process(22850): Sending signal. PID: 22850 SIG: 9
You never initialize bottomGridArray. Nor topGridArray , for that matter. (Look at this topic in a basic Java tutorial to see how and why you need to initialize your arrays)
Before your line
for(int x = 0; x < numberColumn ; x++ )
{
for(int y = 0; y < numberRow ; y++ )
insert
bottomGridArray = new ImageGrid[numberColumn][numberRow];
topGridArray = new ImageGrid[numberColumn][numberRow];
Mind you: Your code probably will have a lot of trouble. You probably should take a look at Google's recommendations for Bitmaps in your UI.
Related
I'm struggling with an Android activity lifecycle issue: When I return to an activity from its child activity, all the instance variables are null, even though they should have been initialized in the onCreate() method of the activity. As you can see below, the SignSearchActivity works fine as long as I stay on the activity. Orientation changes are no problem. As soon as I navigate to the child activity SignSearch_Video_Activity and navigate back up again, a NullPointerException is thrown in the SignSearchActivity.onStart() method. As you can see from the log output the SignSearchActivity.onCreate() method is actually called before the onStart() method. I've had a very similar issue in the SignSearchActivity.onPostExecute() method, but I was able to find a workaround for that (see FIXME code below). Now, I'm really stuck.
Any help very much appreciated.
Best
Matthias
Searching for a string triggers normal lifecycle flow (instance hashCode at the end)
03-20 17:34:25.187 5980-5980/de.foo.bar.baz D/SignBrowserUIFragment: onPause
03-20 17:34:25.201 5980-5980/de.foo.bar.baz D/SignSearchActivity: onCreate() 81236595
03-20 17:34:25.250 5980-5980/de.foo.bar.baz D/SignSearchActivity: setupRecyclerView() 81236595
03-20 17:34:25.251 5980-5980/de.foo.bar.baz D/SignSearchActivity: setupSupportActionBar() 81236595
03-20 17:34:25.252 5980-5980/de.foo.bar.baz D/SignSearchActivity: initSignSearchTaskFragment() 81236595
03-20 17:34:25.253 5980-5980/de.foo.bar.baz D/SignSearchActivity: onStart() 81236595
03-20 17:34:25.254 5980-5980/de.foo.bar.baz D/SignSearchActivity: onPreExecute 81236595
03-20 17:34:25.257 5980-6295/de.foo.bar.baz D/SignDAO: Opening database.
03-20 17:34:25.261 5980-6295/de.foo.bar.baz I/SQLiteAssetHelper: successfully opened database signs.db
03-20 17:34:25.262 5980-6295/de.foo.bar.baz D/SignDAO: Reading signs with name_locale_de like: ma
03-20 17:34:25.264 5980-6295/de.foo.bar.baz D/SignDAO: Closing database.
03-20 17:34:25.311 5980-5980/de.foo.bar.baz D/SignSearchActivity: onCreateOptionsMenu()81236595
03-20 17:34:25.326 5980-5980/de.foo.bar.baz D/SignSearchActivity: onPostExecute 81236595
03-20 17:34:25.382 5980-5980/de.foo.bar.baz D/MainActivity: onSaveInstance
03-20 17:34:25.390 5980-5980/de.foo.bar.baz D/SignBrowserUIFragment: onSaveInstance
Orientation change will saveInstance and create a new instance of SignSearchActivity (see hashCode at the end)
03-20 17:36:21.849 5980-5980/de.foo.bar.baz D/SignSearchActivity: onPause()81236595
>> 03-20 17:36:21.849 5980-5980/de.foo.bar.baz D/SignSearchActivity: onSaveInstanceState() 81236595
03-20 17:36:21.862 5980-6039/de.foo.bar.baz E/Surface: getSlotFromBufferLocked: unknown buffer: 0xb87d8f40
>> 03-20 17:36:21.898 5980-5980/de.foo.bar.baz D/SignSearchActivity: onCreate() 169372560
03-20 17:36:21.914 5980-5980/de.foo.bar.baz D/SignSearchActivity: setupRecyclerView() 169372560
03-20 17:36:21.914 5980-5980/de.foo.bar.baz D/SignSearchActivity: setupSupportActionBar() 169372560
03-20 17:36:21.933 5980-5980/de.foo.bar.baz D/SignSearchActivity: onStart() 169372560
03-20 17:36:21.933 5980-5980/de.foo.bar.baz D/SignSearchActivity: onPreExecute 169372560
03-20 17:36:21.939 5980-6296/de.foo.bar.baz D/SignDAO: Opening database.
03-20 17:36:21.945 5980-6296/de.foo.bar.baz I/SQLiteAssetHelper: successfully opened database signs.db
03-20 17:36:21.946 5980-6296/de.foo.bar.baz D/SignDAO: Reading signs with name_locale_de like: ma
03-20 17:36:21.947 5980-6296/de.foo.bar.baz D/SignDAO: Closing database.
03-20 17:36:21.973 5980-5980/de.foo.bar.baz D/SignSearchActivity: onCreateOptionsMenu()169372560
03-20 17:36:21.994 5980-5980/de.foo.bar.baz D/SignSearchActivity: onPostExecute 169372560
Clicking on a sign will also saveInstance
03-20 17:56:54.415 5980-5980/de.foo.bar.baz D/SignSearchActivity: onTxtSignNameClicked() 169372560
03-20 17:56:54.456 5980-5980/de.foo.bar.baz D/SignSearchActivity: onPause()169372560
03-20 17:56:54.472 5980-5980/de.foo.bar.baz D/SignSearchVideoActivity: onCreate()24174267
03-20 17:56:54.509 5980-5980/de.foo.bar.baz D/SignVideoUIFragment: onCreateView
03-20 17:56:54.644 5980-5980/de.foo.bar.baz D/SignVideoUIFragment: onActivityCreated
03-20 17:56:55.129 5980-5980/de.foo.bar.baz D/MediaPlayer: getMetadata
>> 03-20 17:56:55.182 5980-5980/de.foo.bar.baz D/SignSearchActivity: onSaveInstanceState() 169372560
03-20 17:56:55.614 5980-6001/de.foo.bar.baz W/MediaPlayer: info/warning (3, 0)
Clicking on homeAsUpIndicator will cause NullPointerException in SignSearchActitivity
03-20 18:02:40.552 1625-1625/de.foo.bar.baz D/SignSearchVideoActivity: onPause()24174267
03-20 18:02:40.635 1625-1625/de.foo.bar.baz D/SignSearchActivity: onCreate() 188070473
03-20 18:02:40.654 1625-1625/de.foo.bar.baz D/SignSearchActivity: onStart() 188070473
03-20 18:02:40.659 1625-1625/de.foo.bar.baz D/AndroidRuntime: Shutting down VM
03-20 18:02:40.672 1625-1625/de.foo.bar.baz E/AndroidRuntime: FATAL EXCEPTION: main
Process: de.foo.bar.baz, PID: 1625
java.lang.RuntimeException: Unable to start activity ComponentInfo{de.foo.bar.baz/de.foo.bar.baz.sign_browser.search.SignSearchActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean de.foo.bar.baz.sign_browser.search.SignSearchTaskFragment.isRunning()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2426)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean de.foo.bar.baz.sign_browser.search.SignSearchTaskFragment.isRunning()' on a null object reference
at de.foo.bar.baz.sign_browser.search.SignSearchActivity.onStart(SignSearchActivity.java:91)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1260)
at android.app.Activity.performStart(Activity.java:6261)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2389)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2490)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1354)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5443)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
SignSearchActivity
package de.foo.bar.baz.sign_browser.search;
import android.app.FragmentTransaction;
import android.app.SearchManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.List;
import de.foo.bar.baz.R;
import de.foo.bar.baz.database.Sign;
import de.foo.bar.baz.sign_browser.search.video.SignSearchVideoActivity;
import de.foo.bar.baz.sign_browser.video.SignVideoUIFragment;
public class SignSearchActivity extends AppCompatActivity implements SignSearchTaskFragment.TaskCallbacks {
private static final java.lang.String KEY_QUERY = "sign_browser_search_query";
private static final String TAG_TASK_FRAGMENT = "sign_browser_search_task_fragment";
private static final String TAG = SignSearchActivity.class.getSimpleName();
private SignSearchTaskFragment signSearchTaskFragment;
private String query = StringUtils.EMPTY;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate() " + this.hashCode());
super.onCreate(savedInstanceState);
setContentView(R.layout.search_activity);
if (null != savedInstanceState) {
this.query = savedInstanceState.getString(KEY_QUERY);
} else {
final Intent intent = getIntent();
if (!(Intent.ACTION_SEARCH.equals(intent.getAction()))) {
return;
}
this.query = intent.getStringExtra(SearchManager.QUERY);
}
setupRecyclerView();
setupSupportActionBar();
this.signSearchTaskFragment = (SignSearchTaskFragment) getFragmentManager().findFragmentByTag(TAG_TASK_FRAGMENT);
if (null == this.signSearchTaskFragment) {
initSignSearchTaskFragment();
}
}
private void initSignSearchTaskFragment() {
Log.d(TAG, "initSignSearchTaskFragment() " + this.hashCode());
this.signSearchTaskFragment = new SignSearchTaskFragment();
final FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.add(signSearchTaskFragment, TAG_TASK_FRAGMENT);
fragmentTransaction.commit();
}
private void setupRecyclerView() {
Log.d(TAG, "setupRecyclerView() " + this.hashCode());
final RecyclerView recyclerView = (RecyclerView) this.findViewById(R.id.signSearchRecyclerView);
// recyclerView.setHasFixedSize(true); // performance fix
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(new SignSearchAdapter(new ArrayList<Sign>(), this));
}
private void setupSupportActionBar() {
Log.d(TAG, "setupSupportActionBar() " + this.hashCode());
final ActionBar supportActionBar = getSupportActionBar();
if (null == supportActionBar) {
throw new IllegalStateException("SupportActionBar is null. Should have been set in " +
"onCreate().");
}
supportActionBar.setTitle(getResources().getString(R.string.search_results) + StringUtils.SPACE + this.query);
supportActionBar.setDisplayHomeAsUpEnabled(true);
}
#Override
public void onStart() {
Log.d(TAG, "onStart() " + this.hashCode());
super.onStart();
// if (null != this.signSearchTaskFragment) {
if (!this.signSearchTaskFragment.isRunning()) {
this.signSearchTaskFragment.start(this, query);
}
// }
}
#Override
protected void onPause() {
Log.d(TAG, "onPause()" + this.hashCode());
super.onPause();
if (signSearchTaskFragment.isRunning()) {
this.signSearchTaskFragment.cancel();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.d(TAG, "onCreateOptionsMenu()" + this.hashCode());
final MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.options_sign_browser_search, menu);
final SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
final MenuItem searchItem = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
return true;
}
#Override
public void onSaveInstanceState(Bundle outState) {
Log.d(TAG, "onSaveInstanceState() " + this.hashCode());
super.onSaveInstanceState(outState);
outState.putString(KEY_QUERY, this.query);
}
public void onTxtSignNameClicked(Sign sign) {
Log.d(TAG, "onTxtSignNameClicked() " + this.hashCode());
final Intent intent = new Intent(this, SignSearchVideoActivity.class);
final Bundle bundle = new Bundle();
bundle.putParcelable(SignVideoUIFragment.SIGN_TO_SHOW, sign);
intent.putExtra(SignSearchVideoActivity.EXTRA, bundle);
startActivity(intent);
// final Intent intent = new Intent(this, LevelOneActivity.class);
// final Bundle bundle = new Bundle();
// bundle.putString(LevelOneActivity.FRAGMENT_TO_SHOW, SignVideoUIFragment.class.getSimpleName());
// bundle.putParcelable(SignVideoUIFragment.SIGN_TO_SHOW, sign);
// intent.putExtra(LevelOneActivity.EXTRA, bundle);
// startActivity(intent);
}
#Override
public void onPreExecute() {
Log.d(TAG, "onPreExecute " + this.hashCode());
/*no-op*/
}
#Override
public void onProgressUpdate(int percent) {
Log.d(TAG, "onProgressUpdate " + this.hashCode());
/*no-op*/
}
#Override
public void onCancelled() {
Log.d(TAG, "onCancelled " + this.hashCode());
/*no-op*/
}
#Override
public void onPostExecute(List<Sign> result) {
Log.d(TAG, "onPostExecute " + this.hashCode());
// FIXME: After savedInstance has been called, this.recyclerview is null here, despite being
// FIXME: set in the onCreated() method. Therefore a findViewById is necessary.
final RecyclerView mRecyclerView = (RecyclerView) this.findViewById(R.id.signSearchRecyclerView);
if (null == mRecyclerView) {
throw new IllegalStateException("mRecyclerView is null");
}
mRecyclerView.swapAdapter(new SignSearchAdapter(result, this), false);
}
}
SignSearch_Video_Activity
package de.foo.bar.baz.sign_browser.search.video;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import org.apache.commons.lang3.StringUtils;
import de.foo.bar.baz.R;
import de.foo.bar.baz.sign_browser.video.SignVideoUIFragment;
public class SignSearchVideoActivity extends AppCompatActivity {
public static final String TAG = SignSearchVideoActivity.class.getSimpleName();
public static final String EXTRA = "extra";
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate()" + this.hashCode());
super.onCreate(savedInstanceState);
setContentView(R.layout.search_video_activity);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (null != getSupportActionBar()) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(StringUtils.EMPTY);
}
final Intent intent = getIntent();
final Bundle bundle = intent.getBundleExtra(EXTRA);
if (null == bundle) {
throw new IllegalArgumentException("The bundle supplied to the activity is null");
}
final Parcelable sign = bundle.getParcelable(SignVideoUIFragment.SIGN_TO_SHOW);
final SignVideoUIFragment signVideoUIFragment = new SignVideoUIFragment();
final Bundle args = new Bundle();
args.putParcelable(SignVideoUIFragment.SIGN_TO_SHOW, sign);
signVideoUIFragment.setArguments(args);
final FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.searchVideoActivityContentFrame, signVideoUIFragment, "SIGN_VIDEO_TAG");
transaction.addToBackStack(null);
transaction.commit();
}
#Override
protected void onPause() {
Log.d(TAG, "onPause()" + this.hashCode());
super.onPause();
setResult(RESULT_OK);
}
}
Figured it out myself:
The problem was that even though the onCreate() method of the SignSearchActivity was executed, vital parts of it were not. This was due to the fact that the child activity did not call the SignSearchActivity (which is backing a SearchView) with the right kind of intent.
So this code
if (!(Intent.ACTION_SEARCH.equals(intent.getAction()))) {
return;
}
meant that the SignSearch.onCreate() method returned when it wasn't supposed to.
Now, the SignSearchActivity passes the query to the SignSearchVideoActivity as an intent extra. When the SignSearchVideoActivity navigates back up to the SignSearchActivity, it passes the original query back again.
Modified SignSearchActivity.onCreate() method.
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "onCreate() " + this.hashCode());
super.onCreate(savedInstanceState);
setContentView(R.layout.search_activity);
if (null != savedInstanceState) {
this.query = savedInstanceState.getString(QUERY);
} else {
final Intent intent = getIntent();
this.query = intent.getStringExtra(SearchManager.QUERY);
Validate.notNull(this.query, "The query supplied to this activity is null!");
}
setupRecyclerView();
setupSupportActionBar();
this.signSearchTaskFragment = (SignSearchTaskFragment) getFragmentManager().findFragmentByTag(TAG_TASK_FRAGMENT);
if (null == this.signSearchTaskFragment) {
initSignSearchTaskFragment();
}
}
New SignSearchVideoActivity.onOptionItemsSelected() method.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.d(TAG, "onOptionsItemSelected() " + this.hashCode());
switch (item.getItemId()) {
case android.R.id.home:
final Intent upIntent = NavUtils.getParentActivityIntent(this);
upIntent.putExtra(SearchManager.QUERY, this.originalQuery);
NavUtils.navigateUpTo(this, upIntent);
return true;
}
return super.onOptionsItemSelected(item);
}
I'm studying Android development. I have a problem in LogCat, it seems like it is unable to start settings activity:
05-06 09:40:37.323: E/AndroidRuntime(945): FATAL EXCEPTION: main
05-06 09:40:37.323: E/AndroidRuntime(945): Process: com.androiddevbook.onyourbike_chapter4, PID: 945
05-06 09:40:37.323: E/AndroidRuntime(945): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.androiddevbook.onyourbike_chapter4/com.androiddevbook.onyourbike_chapter5.activities.SettingsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setDisplayHomeAsUpEnabled(boolean)' on a null object reference
05-06 09:40:37.323: E/AndroidRuntime(945): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
05-06 09:40:37.323: E/AndroidRuntime(945): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
05-06 09:40:37.323: E/AndroidRuntime(945): at android.app.ActivityThread.access$800(ActivityThread.java:144)
05-06 09:40:37.323: E/AndroidRuntime(945): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
05-06 09:40:37.323: E/AndroidRuntime(945): at android.os.Handler.dispatchMessage(Handler.java:102)
05-06 09:40:37.323: E/AndroidRuntime(945): at android.os.Looper.loop(Looper.java:135)
05-06 09:40:37.323: E/AndroidRuntime(945): at android.app.ActivityThread.main(ActivityThread.java:5221)
05-06 09:40:37.323: E/AndroidRuntime(945): at java.lang.reflect.Method.invoke(Native Method)
05-06 09:40:37.323: E/AndroidRuntime(945): at java.lang.reflect.Method.invoke(Method.java:372)
05-06 09:40:37.323: E/AndroidRuntime(945): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
05-06 09:40:37.323: E/AndroidRuntime(945): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
05-06 09:40:37.323: E/AndroidRuntime(945): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setDisplayHomeAsUpEnabled(boolean)' on a null object reference
05-06 09:40:37.323: E/AndroidRuntime(945): at com.androiddevbook.onyourbike_chapter5.activities.SettingsActivity.setupActionBar(SettingsActivity.java:48)
05-06 09:40:37.323: E/AndroidRuntime(945): at com.androiddevbook.onyourbike_chapter5.activities.SettingsActivity.onCreate(SettingsActivity.java:40)
05-06 09:40:37.323: E/AndroidRuntime(945): at android.app.Activity.performCreate(Activity.java:5933)
05-06 09:40:37.323: E/AndroidRuntime(945): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
05-06 09:40:37.323: E/AndroidRuntime(945): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
05-06 09:40:37.323: E/AndroidRuntime(945): ... 10 more
Here is class where make intent with function clickedSettings for calling SettingsActivity.class Activity ( in runtime when is clicked Settings on the actionBar on top of the screen) :
package com.androiddevbook.onyourbike_chapter5.activities;
import com.androiddevbook.onyourbike_chapter4.BuildConfig;
import com.androiddevbook.onyourbike_chapter4.R;
import com.androiddevbook.onyourbike_chapter5.model.TimerState;
import android.support.v7.app.ActionBarActivity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.StrictMode;
import android.os.Vibrator;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class TimerActivity extends ActionBarActivity {
private static String CLASS_NAME;
protected TextView counter;
protected Button start;
protected Button stop;
protected Handler handler;
protected UpdateTimer updateTimer;
private static long UPDATE_EVERY = 200;
protected Vibrator vibrate;
protected long lastSeconds;
private TimerState timer;
public TimerActivity(){
CLASS_NAME = getClass().getName();
timer = new TimerState();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
counter = (TextView) findViewById(R.id.timer);
start = (Button) findViewById(R.id.start_button);
stop = (Button) findViewById(R.id.stop_button);
Log.d(CLASS_NAME, "Setting text.");
if (BuildConfig.DEBUG){
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectAll().penaltyLog().build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectAll().penaltyLog().penaltyDeath().build());
}
timer.reset();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.d(CLASS_NAME, "Showing menu.");
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#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_settings) {
Log.d(CLASS_NAME, "SETTINGS PRESSED.");
System.out.println("Settings pressed.");
clickedSettings(null);
return true;
}
return super.onOptionsItemSelected(item);
}
public void clickedStart(View view){
Log.d(CLASS_NAME, "Clicked start button.");
timer.start();
enableButtons();
handler = new Handler();
updateTimer = new UpdateTimer();
handler.postDelayed(updateTimer, UPDATE_EVERY);
}
public void clickedStop(View view){
Log.d(CLASS_NAME, "Clicked stop button.");
timer.stop();
enableButtons();
handler.removeCallbacks(updateTimer);
updateTimer = null;
handler = null;
}
public void enableButtons(){
Log.d(CLASS_NAME, "Set buttons enabled/disabled.");
start.setEnabled(!timer.isRunning());
stop.setEnabled(timer.isRunning());
}
public class UpdateTimer implements Runnable {
public void run(){
Log.d(CLASS_NAME, "run");
setTimeDisplay();
if ( handler != null){
handler.postDelayed(this, UPDATE_EVERY);
}
if ( timer.isRunning() ){
vibrateCheck();
}
}
}
public void onStart(){
super.onStart();
Log.d(CLASS_NAME, "onStart");
if ( timer.isRunning() ){
handler = new Handler();
updateTimer = new UpdateTimer();
handler.postDelayed(updateTimer, UPDATE_EVERY);
}
vibrate = (Vibrator) getSystemService(VIBRATOR_SERVICE);
if (vibrate == null){
Log.w(CLASS_NAME, "No vibrate service exists.");
}
}
public void onPause(){
super.onPause();
Log.d(CLASS_NAME, "onPause");
}
public void onResume(){
super.onResume();
Log.d(CLASS_NAME, "onResume");
}
public void onStop(){
super.onStop();
Log.d(CLASS_NAME, "onSop");
if ( timer.isRunning() ){
handler.removeCallbacks(updateTimer);
handler = null;
updateTimer = null;
}
}
public void onDestroy(){
super.onDestroy();
Log.d(CLASS_NAME, "onDestroy");
}
public void onRestart(){
super.onRestart();
Log.d(CLASS_NAME, "onRestart");
}
protected void vibrateCheck(){
long diff = timer.elapsedTime();
long seconds = diff / 1000;
long minutes = seconds / 60;
seconds = seconds % 60;
minutes = minutes % 60;
Log.d(CLASS_NAME, "vibrateCheck");
if ( vibrate != null && seconds == 0 && seconds != lastSeconds){
long[] once = { 0, 100 };
long[] twice= { 0, 100, 400, 100};
long[] thrice = { 0, 100, 400, 100, 400, 100 };
// every hour
if ( minutes == 0){
Log.d(CLASS_NAME, "Vibrate 3 times");
vibrate.vibrate(thrice, -1);
}
// every 15 minutes
else if ( minutes % 15 == 0 ){
Log.d(CLASS_NAME, "Vibrate 2 times");
vibrate.vibrate(twice, -1);
}
// every 1 minute
else if ( minutes == 1 ){
Log.d(CLASS_NAME, "Vibrate 1 time");
vibrate.vibrate(once, -1);
}
}
lastSeconds = seconds;
}
public void clickedSettings(View view){
Log.d(CLASS_NAME, "clickedSettings.");
Intent settingsIntent = new Intent(this, SettingsActivity.class);
startActivity(settingsIntent);
}
public void setTimeDisplay(){
Log.d(CLASS_NAME, "setTimeDisplay");
counter.setText(timer.display());
}
}
And here is SettingsActivity class, where keep options for vibrate:
package com.androiddevbook.onyourbike_chapter5.activities;
import com.androiddevbook.onyourbike.chapter5.helpers.Toaster;
import com.androiddevbook.onyourbike_chapter4.R;
import com.androiddevbook.onyourbike_chapter5.OnYourBike;
import com.androiddevbook.onyourbike_chapter5.model.Settings;
import android.support.v7.app.ActionBarActivity;
import android.annotation.TargetApi;
import android.app.ActionBar;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.CheckBox;
public class SettingsActivity extends ActionBarActivity {
private CheckBox vibrate;
private String CLASS_NAME = "dada";
public SettingsActivity(){
Log.d(CLASS_NAME, "SettingsActivity.class....");
CLASS_NAME = getClass().getName();
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupActionBar() {
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
ActionBar actionBar = getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
vibrate = (CheckBox)
findViewById(R.id.vibrate_checkbox);
Settings settings = ((OnYourBike)getApplication()).getSettings();
vibrate.setChecked(settings.isVibrateOn(this));
setupActionBar();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.settings, menu);
return true;
}
#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.home) {
goHome();
return true;
}
return super.onOptionsItemSelected(item);
}
private void goHome() {
Log.d(CLASS_NAME, "gotoHome");
Intent timer =
new Intent(this, TimerActivity.class);
timer.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(timer);
}
public void onStop(){
super.onStop();
Settings settings = ((OnYourBike)getApplication()).getSettings();
settings.setVibrate(this, vibrate.isChecked());
}
public void vibrateChanged(View view){
Toaster toast = new Toaster(getApplicationContext());
if(vibrate.isChecked())
toast.make(R.string.vibrate_on);
else
toast.make(R.string.vibrate_off);
}
public void goBack(View view){
finish();
}
}
And finnaly, spec about my virtual telephone:
CPU/ABI: ARM (armeabi-v7a)
Target: Android 5.0.1 ( API level 21)
As you Extends ActionBarActivity so you need to get ActionBar using
ActionBar actionBar = getSupportActionBar();
According to the error log:
05-06 09:40:37.323: E/AndroidRuntime(945): Process: com.androiddevbook.onyourbike_chapter4, PID: 945
05-06 09:40:37.323: E/AndroidRuntime(945): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.androiddevbook.onyourbike_chapter4/com.androiddevbook.onyourbike_chapter5.activities.SettingsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setDisplayHomeAsUpEnabled(boolean)' on a null object reference
ActionBar actionBar = getActionBar(); line returns a null object.
Reasons:
ActionBarActivity subclasses FragmentActivity which is a support component, change code to ActionBar actionBar = getSupportActionBar();
You might be using a theme like ...Light.NoActionBar, so this due to this also there is no ActionBar present for activities, change theme to a theme that support ActionBar.
Another thing to note, this isn't the reason of this issue but, is that ActionBarActivity is deprecated, use AppCompatActivity from now on.
Your error log says it all:
05-06 09:40:37.323: E/AndroidRuntime(945): Process: com.androiddevbook.onyourbike_chapter4, PID: 945
05-06 09:40:37.323: E/AndroidRuntime(945): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.androiddevbook.onyourbike_chapter4/com.androiddevbook.onyourbike_chapter5.activities.SettingsActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.ActionBar.setDisplayHomeAsUpEnabled(boolean)' on a null object reference
You are calling a method on a null object:
actionBar.setDisplayHomeAsUpEnabled(true);
So make sure you do a null check or you might need to use getSupportActionBar
change your setupActionBar method like this:
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupActionBar() {
if ( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
Here, this is detailActivity.java which gathers data from openWeatherAPI and populates the data into a listView. When I click on the item on listView there is NPE in OnCreateOptionsMenu.
package com.example.sunshine2;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.ShareActionProvider;
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.TextView;
import com.example.sunshine2.data.WeatherContract.WeatherEntry;
public class DetailActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new DetailFragment()).commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.detail, menu);
return true;
}
#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_settings) {
startActivity(new Intent(this, SettingsActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class DetailFragment extends Fragment implements
LoaderCallbacks<Cursor> {
private static final String LOG_TAG = DetailFragment.class
.getSimpleName();
private static final String FORECAST_SHARE_HASHTAG = " #SunshineApp";
private ShareActionProvider mShareActionProvider;
private String mForecast;
private static final int DETAIL_LOADER = 0;
private static final String[] FORECAST_COLUMNS = {
WeatherEntry.TABLE_NAME + "." + WeatherEntry._ID,
WeatherEntry.COLUMN_DATE, WeatherEntry.COLUMN_SHORT_DESC,
WeatherEntry.COLUMN_MAX_TEMP, WeatherEntry.COLUMN_MIN_TEMP, };
// these constants correspond to the projection defined above, and must
// change if the
// projection changes
private static final int COL_WEATHER_ID = 0;
private static final int COL_WEATHER_DATE = 1;
private static final int COL_WEATHER_DESC = 2;
private static final int COL_WEATHER_MAX_TEMP = 3;
private static final int COL_WEATHER_MIN_TEMP = 4;
public DetailFragment() {
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_detail, container, false);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Inflate the menu; this adds items to the action bar if it is
// present.
inflater.inflate(R.menu.detail_fragment, menu);
// Retrieve the share menu item
MenuItem menuItem = menu.findItem(R.id.action_share);
// Get the provider and hold onto it to set/change the share intent.
mShareActionProvider = (ShareActionProvider) MenuItemCompat
.getActionProvider(menuItem);
// If onLoadFinished happens before this, we can go ahead and set
// the share intent now.
if (mForecast != null) {
mShareActionProvider
.setShareIntent(createShareForecastIntent());
}
}
private Intent createShareForecastIntent() {
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
shareIntent.setType("text/plain");
shareIntent.putExtra(Intent.EXTRA_TEXT, mForecast
+ FORECAST_SHARE_HASHTAG);
return shareIntent;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
getLoaderManager().initLoader(DETAIL_LOADER, null, this);
super.onActivityCreated(savedInstanceState);
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
Log.v(LOG_TAG, "In onCreateLoader");
Intent intent = getActivity().getIntent();
if (intent == null) {
return null;
}
// Now create and return a CursorLoader that will take care of
// creating a Cursor for the data being displayed.
return new CursorLoader(getActivity(), intent.getData(),
FORECAST_COLUMNS, null, null, null);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
Log.v(LOG_TAG, "In onLoadFinished");
if (!data.moveToFirst()) {
return;
}
String dateString = Utility.formatDate(data
.getLong(COL_WEATHER_DATE));
String weatherDescription = data.getString(COL_WEATHER_DESC);
boolean isMetric = Utility.isMetric(getActivity());
String high = Utility.formatTemperature(
data.getDouble(COL_WEATHER_MAX_TEMP), isMetric);
String low = Utility.formatTemperature(
data.getDouble(COL_WEATHER_MIN_TEMP), isMetric);
mForecast = String.format("%s - %s - %s/%s", dateString,
weatherDescription, high, low);
TextView detailTextView = (TextView) getView().findViewById(
R.id.detail_text);
detailTextView.setText(mForecast);
// If onCreateOptionsMenu has already happened, we need to update
// the share intent now.
if (mShareActionProvider != null) {
mShareActionProvider
.setShareIntent(createShareForecastIntent());
}
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
}
}
}
And Here is the LogCat
04-13 01:22:51.916: E/AndroidRuntime(20197): FATAL EXCEPTION: main
04-13 01:22:51.916: E/AndroidRuntime(20197): Process: com.example.sunshine2, PID: 20197
04-13 01:22:51.916: E/AndroidRuntime(20197): java.lang.NullPointerException
04-13 01:22:51.916: E/AndroidRuntime(20197): at com.example.sunshine2.DetailActivity$DetailFragment.onCreateOptionsMenu(DetailAc tivity.java:117)
04-13 01:22:51.916: E/AndroidRuntime(20197): at android.support.v4.app.Fragment.performCreateOptionsMenu(Fragment.java:1582)
04-13 01:22:51.916: E/AndroidRuntime(20197): at android.support.v4.app.FragmentManagerImpl.dispatchCreateOptionsMenu(FragmentManager.java:1967)
04-13 01:22:51.916: E/AndroidRuntime(20197): at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:225)
04-13 01:22:51.916: E/AndroidRuntime(20197): at android.support.v7.app.ActionBarActivity.superOnCreatePanelMenu(ActionBarActivity.java:232)
04-13 01:22:51.916: E/AndroidRuntime(20197): at android.support.v7.app.ActionBarActivityDelegateICS.onCreatePanelMenu(ActionBarActivityDelegateICS.java:146)
04-13 01:22:51.916: E/AndroidRuntime(20197): at android.support.v7.app.ActionBarActivity.onCreatePanelMenu(ActionBarActivity.java:199)
04-13 01:22:51.916: E/AndroidRuntime(20197): at android.support.v7.app.ActionBarActivityDelegateICS$WindowCallbackWrapper.onCreatePanelMenu(ActionBarActivityDelegateICS.java:293)
04-13 01:22:51.916: E/AndroidRuntime(20197): at com.android.internal.policy.impl.PhoneWindow.preparePanel(PhoneWindow.java:436)
04-13 01:22:51.916: E/AndroidRuntime(20197): at com.android.internal.policy.impl.PhoneWindow.doInvalidatePanelMenu(PhoneWindow.java:803)
04-13 01:22:51.916: E/AndroidRuntime(20197): at com.android.internal.policy.impl.PhoneWindow$1.run(PhoneWindow.java:221)
04-13 01:22:51.916: E/AndroidRuntime(20197): at android.os.Handler.handleCallback(Handler.java:733)
04-13 01:22:51.916: E/AndroidRuntime(20197): at android.os.Handler.dispatchMessage(Handler.java:95)
04-13 01:22:51.916: E/AndroidRuntime(20197): at android.os.Looper.loop(Looper.java:149)
04-13 01:22:51.916: E/AndroidRuntime(20197): at android.app.ActivityThread.main(ActivityThread.java:5077)
04-13 01:22:51.916: E/AndroidRuntime(20197): at java.lang.reflect.Method.invokeNative(Native Method)
04-13 01:22:51.916: E/AndroidRuntime(20197): at java.lang.reflect.Method.invoke(Method.java:515)
04-13 01:22:51.916: E/AndroidRuntime(20197): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
04-13 01:22:51.916: E/AndroidRuntime(20197): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:609)
04-13 01:22:51.916: E/AndroidRuntime(20197): at dalvik.system.NativeStart.main(Native Method)
I've tried debugging the code, but the
- mShareActionProvider gives me null, which I can't figure out how
I think the problem is you have a onClick function declared in your XML menu layout file but no corresponding function in your code.
I want my android app to display a pop-up window when the internet connection lost in order to tells the user that he lost the connection, I tried to catch null stream and then initiate a pop-up then, but it gives me that exception:
03-20 10:16:35.015: W/System.err(2922):
android.view.WindowManager$BadTokenException: Unable to add window --
token null is not valid; is your activity running?
03-20 10:16:35.016: W/System.err(2922): at android.view.ViewRootImpl.setView(ViewRootImpl.java:646)
03-20 10:16:35.016: W/System.err(2922): at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248)
03-20 10:16:35.016: W/System.err(2922): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
03-20 10:16:35.016: W/System.err(2922): at android.widget.PopupWindow.invokePopup(PopupWindow.java:993)
03-20 10:16:35.016: W/System.err(2922): at android.widget.PopupWindow.showAtLocation(PopupWindow.java:847)
03-20 10:16:35.016: W/System.err(2922): at android.widget.PopupWindow.showAtLocation(PopupWindow.java:811)
03-20 10:16:35.016: W/System.err(2922): at com.example.solaceap.Login$5.run(Login.java:135)
03-20 10:16:35.016: W/System.err(2922): at android.app.Activity.runOnUiThread(Activity.java:4662)
03-20 10:16:35.016: W/System.err(2922): at com.example.solaceap.Login.init_conn_lost_popup(Login.java:119)
03-20 10:16:35.016: W/System.err(2922): at com.example.solaceap.Login$6$1.run(Login.java:281)
03-20 10:16:35.016: W/System.err(2922): at android.os.Handler.handleCallback(Handler.java:725)
03-20 10:16:35.017: W/System.err(2922): at android.os.Handler.dispatchMessage(Handler.java:92)
03-20 10:16:35.017: W/System.err(2922): at android.os.Looper.loop(Looper.java:153)
03-20 10:16:35.017: W/System.err(2922): at android.app.ActivityThread.main(ActivityThread.java:5299)
03-20 10:16:35.017: W/System.err(2922): at java.lang.reflect.Method.invokeNative(Native Method)
03-20 10:16:35.017: W/System.err(2922): at java.lang.reflect.Method.invoke(Method.java:511)
03-20 10:16:35.017: W/System.err(2922): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
03-20 10:16:35.017: W/System.err(2922): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
03-20 10:16:35.017: W/System.err(2922): at dalvik.system.NativeStart.main(Native Method)
I don't know is the app crashed before running or that because as I'm not in the inflated activity at that time, And this is my code:
Worth to mention that the stream is got from a normal java class that implements Runnable not an activity class, as I just ran a thread that keeps giving me Input data from the stream , look at that :
public String getServerResponse() throws JSONException {
String responseLine, server_response = null_string;
InputStream stream = null;
try{
stream = socket.getInputStream();
}catch(Exception e){
e.printStackTrace();
Login login = new Login();
login.init_conn_lost_popup();
}
if(stream != null){
input = new BufferedReader(new InputStreamReader(
stream));
try {
while ((responseLine = input.readLine()) != null){
server_response = server_response + responseLine;
}
} catch (IOException e) {
Login.errorMessage.setText(conn_err);
}
}
return null;
}
And then in the activity that ran the past thread at the first:
Thread run_time = new Thread() {
#Override
public void run() {
ConnectToServer connect = new ConnectToServer(); // this is the Runnable class
while (true) {
String server_response = null;
try {
server_response = connect.getServerRespons(Login.this);
} catch (Exception e1) {
}
try {
if (!server_response.equals(null)) {
}
} catch (Exception e) {
if (!this.isInterrupted()) {
flag = true;
runOnUiThread(new Runnable() {
public void run() {
flag = false;
init_conn_lost_popup();
}
});
}
}
}
}
};
run_time.start();
And this is the pop_up method :
public void init_conn_lost_popup() {
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
LayoutInflater inflater = (LayoutInflater) Login.this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.connection_popup,
(ViewGroup) findViewById(R.id.conn_pop));
// create a 300px width and 470px height PopupWindow
final PopupWindow pw = new PopupWindow(layout,
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT, true);
// display the popup in the center
pw.showAtLocation(layout, Gravity.CENTER, 0, 0); // this is where i'm getting the Exception
}
});
}
And I just made a lot of tries like :
Replacing the inflater with :
getWindow().addContentView(layout,new ViewGroup.LayoutParams (ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT)); // after declaring the Layout View of course
Changing the context (Login.this) to :
1- getApplicationContext().
2- getBaseContext().
3- creating an Application class to retrieve the context from then called the desired method (MyApplication.getAppContext()).as explained here.
Instead of creating popup functionality into activity itself,try to create the seperate activity for it and when internet connection gone,call this activity and while declaring that activity into android manifest file use the following tag
android:theme="#style/Theme.Transparent"
so that you will not get the error even if you are not into application
why don't you just register broadcast receiver, that will notify you when connection is lost? It would be more easier, than that you do now.
private final BroadcastReceiver connectionStateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (!isNetworkAvailable(context)) {
init_conn_lost_popup();
}
}
}
privaate boolean isNetworkAvailable(final Context context) {
ConnectivityManager connectivityManager = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
and now just register this receiver in onResume() method, also unregister it in onPause()
//Declare your AlertDialog here
private AlertDialog alertDialog;
.....
.....
//Your Broadcasr receiver in Mainactivity for connection change info
private BroadcastReceiver networkReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
NetworkInfo networkInfo = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.CONNECTED) {
try {
if (alertDialog != null && alertDialog.isShowing())
alertDialog.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
} else if (networkInfo != null && networkInfo.getDetailedState() == NetworkInfo.DetailedState.DISCONNECTED) {
if (alertDialog == null || !alertDialog.isShowing()) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
//Define your custom layout here
LayoutInflater inflater = getLayoutInflater();
View dialoglayout = inflater.inflate(R.layout.dialog_networl_lost, null);
builder.setView(dialoglayout);
builder.setCancelable(false);
alertDialog = builder.create();
alertDialog.show();
}
}
}
}
};
#Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(networkReceiver, intentFilter);
}
#Override
protected void onPause() {
super.onPause();
if (networkReceiver != null)
unregisterReceiver(networkReceiver);
}
I'm trying to show an about page to the users of my wallpaper app when they click the about button however i get leaked window errors in a log cat and the activity quits before it shows the dialog.
Here is the code:
/*
*
* Sensational Wallpapers Pack 1
*
* Wallpaper Designed by AZ2ENVY
*
*/
package com.death2all110.SensationalWallpapers1;
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.AsyncTask;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.Toast;
import android.app.AlertDialog;
import android.widget.Button;
import android.content.DialogInterface;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import com.death2all110.SensationalWallpapers1.R;
public class wallpaper extends Activity implements AdapterView.OnItemSelectedListener,
OnClickListener {
private Gallery mGallery;
private ImageView mImageView;
private boolean mIsWallpaperSet;
private Bitmap mBitmap;
private ArrayList<Integer> mThumbs;
private ArrayList<Integer> mImages;
private WallpaperLoader mLoader;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
requestWindowFeature(Window.FEATURE_NO_TITLE);
findWallpapers();
setContentView(R.layout.wallpaper_chooser);
mGallery = (Gallery) findViewById(R.id.gallery);
mGallery.setAdapter(new ImageAdapter(this));
mGallery.setOnItemSelectedListener(this);
mGallery.setCallbackDuringFling(false);
findViewById(R.id.set).setOnClickListener(this);
mImageView = (ImageView) findViewById(R.id.wallpaper);
Button alert = (Button) findViewById(R.id.about_page);
alert.setOnClickListener(this);
}
private void findWallpapers() {
mThumbs = new ArrayList<Integer>(24);
mImages = new ArrayList<Integer>(24);
final Resources resources = getResources();
final String packageName = getApplication().getPackageName();
addWallpapers(resources, packageName, R.array.wallpapers);
addWallpapers(resources, packageName, R.array.extra_wallpapers);
}
private void addWallpapers(Resources resources, String packageName, int list) {
final String[] extras = resources.getStringArray(list);
for (String extra : extras) {
int res = resources.getIdentifier(extra, "drawable", packageName);
if (res != 0) {
final int thumbRes = resources.getIdentifier(extra + "_small",
"drawable", packageName);
if (thumbRes != 0) {
mThumbs.add(thumbRes);
mImages.add(res);
}
}
}
}
#Override
protected void onResume() {
super.onResume();
mIsWallpaperSet = false;
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mLoader != null && mLoader.getStatus() != WallpaperLoader.Status.FINISHED) {
mLoader.cancel(true);
mLoader = null;
}
}
public void onItemSelected(AdapterView parent, View v, int position, long id) {
if (mLoader != null && mLoader.getStatus() != WallpaperLoader.Status.FINISHED) {
mLoader.cancel();
}
mLoader = (WallpaperLoader) new WallpaperLoader().execute(position);
}
/*
* When using touch if you tap an image it triggers both the onItemClick and
* the onTouchEvent causing the wallpaper to be set twice. Ensure we only
* set the wallpaper once.
*/
private void selectWallpaper(int position) {
if (mIsWallpaperSet) {
return;
}
mIsWallpaperSet = true;
try {
InputStream stream = getResources().openRawResource(mImages.get(position));
setWallpaper(stream);
setResult(RESULT_OK);
finish();
} catch (IOException e) {
Log.e("Paperless System", "Failed to set wallpaper: " + e);
}
}
public void onNothingSelected(AdapterView parent) {
}
private class ImageAdapter extends BaseAdapter {
private LayoutInflater mLayoutInflater;
ImageAdapter(wallpaper context) {
mLayoutInflater = context.getLayoutInflater();
}
public int getCount() {
return mThumbs.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView image;
if (convertView == null) {
image = (ImageView) mLayoutInflater.inflate(R.layout.wallpaper_item, parent, false);
} else {
image = (ImageView) convertView;
}
int thumbRes = mThumbs.get(position);
image.setImageResource(thumbRes);
Drawable thumbDrawable = image.getDrawable();
if (thumbDrawable != null) {
thumbDrawable.setDither(true);
} else {
Log.e("Paperless System", String.format(
"Error decoding thumbnail resId=%d for wallpaper #%d",
thumbRes, position));
}
return image;
}
}
public void onClick(View v) {
selectWallpaper(mGallery.getSelectedItemPosition());
}
public void onClick1(View about) {
// If "About was clicked.....
if (about == findViewById(R.id.about_page)) {
// Prepare the alert box!!
AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
// Set message to display...
alertbox.setMessage("Test.....");
// Add a neutral button to the alert box AND assign a listener for said button...
alertbox.setNeutralButton("Ok", new DialogInterface.OnClickListener(){
// click listener for box
public void onClick(DialogInterface arg0, int arg1){
// Button was clicked!!
Toast.makeText(getApplicationContext(), "Dialog closed successfully!", Toast.LENGTH_LONG).show();
}
});
// show it!!!
alertbox.show();
}
}
class WallpaperLoader extends AsyncTask<Integer, Void, Bitmap> {
BitmapFactory.Options mOptions;
WallpaperLoader() {
mOptions = new BitmapFactory.Options();
mOptions.inDither = false;
mOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
}
protected Bitmap doInBackground(Integer... params) {
if (isCancelled()) return null;
try {
return BitmapFactory.decodeResource(getResources(),
mImages.get(params[0]), mOptions);
} catch (OutOfMemoryError e) {
return null;
}
}
#Override
protected void onPostExecute(Bitmap b) {
if (b == null) return;
if (!isCancelled() && !mOptions.mCancel) {
// Help the GC
if (mBitmap != null) {
mBitmap.recycle();
}
final ImageView view = mImageView;
view.setImageBitmap(b);
mBitmap = b;
final Drawable drawable = view.getDrawable();
drawable.setFilterBitmap(true);
drawable.setDither(true);
view.postInvalidate();
mLoader = null;
} else {
b.recycle();
}
}
void cancel() {
mOptions.requestCancelDecode();
super.cancel(true);
}
}
}
Here is the logcat:
I/ActivityManager( 59): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.death2all110.SensationalWallpapers1/.wallpaper }
I/ActivityManager( 59): Displayed activity com.death2all110.SensationalWallpapers1/.wallpaper: 474 ms (total 474 ms)
D/dalvikvm( 286): GC freed 1448 objects / 151304 bytes in 131ms
D/dalvikvm( 106): GC freed 2485 objects / 144824 bytes in 245ms
D/dalvikvm( 59): threadid=15: bogus mon 1+0>0; adjusting
D/dalvikvm( 59): GC freed 3666 objects / 207344 bytes in 360ms
D/dalvikvm( 59): GC freed 459 objects / 21096 bytes in 357ms
E/WindowManager( 286): Activity com.death2all110.SensationalWallpapers1.wallpaper has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView#44c0f3d0 that was originally added here
E/WindowManager( 286): android.view.WindowLeaked: Activity com.death2all110.SensationalWallpapers1.wallpaper has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView#44c0f3d0 that was originally added here
E/WindowManager( 286): at android.view.ViewRoot.<init>(ViewRoot.java:227)
E/WindowManager( 286): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
E/WindowManager( 286): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
E/WindowManager( 286): at android.view.Window$LocalWindowManager.addView(Window.java:424)
E/WindowManager( 286): at android.app.Dialog.show(Dialog.java:239)
E/WindowManager( 286): at android.app.AlertDialog$Builder.show(AlertDialog.java:802)
E/WindowManager( 286): at com.death2all110.SensationalWallpapers1.wallpaper.onClick(wallpaper.java:244)
E/WindowManager( 286): at android.view.View.performClick(View.java:2364)
E/WindowManager( 286): at android.view.View.onTouchEvent(View.java:4179)
E/WindowManager( 286): at android.widget.TextView.onTouchEvent(TextView.java:6541)
E/WindowManager( 286): at android.view.View.dispatchTouchEvent(View.java:3709)
E/WindowManager( 286): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
E/WindowManager( 286): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
E/WindowManager( 286): at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:884)
E/WindowManager( 286): at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1659)
E/WindowManager( 286): at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
E/WindowManager( 286): at android.app.Activity.dispatchTouchEvent(Activity.java:2061)
E/WindowManager( 286): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1643)
E/WindowManager( 286): at android.view.ViewRoot.handleMessage(ViewRoot.java:1691)
E/WindowManager( 286): at android.os.Handler.dispatchMessage(Handler.java:99)
E/WindowManager( 286): at android.os.Looper.loop(Looper.java:123)
E/WindowManager( 286): at android.app.ActivityThread.main(ActivityThread.java:4363)
E/WindowManager( 286): at java.lang.reflect.Method.invokeNative(Native Method)
E/WindowManager( 286): at java.lang.reflect.Method.invoke(Method.java:521)
E/WindowManager( 286): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
E/WindowManager( 286): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
E/WindowManager( 286): at dalvik.system.NativeStart.main(Native Method)
D/dalvikvm( 286): GC freed 1704 objects / 168544 bytes in 330ms
Not only does it have a leaked window, but when that button is clicked it also sets the wallpaper...
Any help would be greatly appreciated
change this
AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
with
AlertDialog.Builder alertbox = new AlertDialog.Builder(yourActivity.this);
EDITED:
Button alert = (Button) findViewById(R.id.about_page);
alert.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// do ur logic
});
make above change to your button click
The error shows that you are using the bad context here,
AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
Try to use the right context here,
getApplicationContext(); or getParent() may solve your issue...
Thanks,
Suri Sahani.