i have an a fragment that have a background thread that update a progress bar value and change the progress bar drawable when the progress value reach a certain value when i try to start onther fragment in the same activity it case this error
E/UncaughtException: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.support.v4.app.FragmentActivity.getResources()' on a null object reference
at com.example.mego.adas.ui.CarFragment$PotProgressThread$1.run(CarFragment.java:831)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7409)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.mego.adas, PID: 25935
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.support.v4.app.FragmentActivity.getResources()' on a null object reference
at com.example.mego.adas.ui.CarFragment$PotProgressThread$1.run(CarFragment.java:831)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7409)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
here is the code for the thread
class PotProgressThread implements Runnable {
@Override
public void run() {
while (potSensorValue <= 1025 && fragmentIsRunning) {
if (fragmentIsRunning) {
// Update the progress bar
potProgressBarHandler.post(new Runnable() {
public void run() {
potProgressBar.setProgress((int) potSensorValue);
if (potSensorValue >= 800) {
potProgressBar.setProgressDrawable(getActivity().
getResources().getDrawable(R.drawable.progressbarred));
} else {
potProgressBar.setProgressDrawable(getActivity().
getResources().getDrawable(R.drawable.progressbarblue));
}
}
});
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
break;
}
}
}
}
Here where i cast start my thread in onCreateView() method
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_car, container, false);
initializeScreen(rootView);
//check the internet connection
connectivityManager = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
buildGoogleApiClient();
//set up the firebase
mFirebaseDatabase = FirebaseDatabase.getInstance();
//get the references for the childes
//the main child for the directions services
carDatabaseReference = mFirebaseDatabase.getReference().child(constant.FIREBASE_CAR);
//the childes for the direction root
connectionStateDatabaseReference = mFirebaseDatabase.getReference()
.child(constant.FIREBASE_CAR).child(constant.FIREBASE_CONNECTION_STATE);
accidentStateDatabaseReference = mFirebaseDatabase.getReference()
.child(constant.FIREBASE_CAR).child(constant.FIREBASE_ACCIDENT_STATE);
startStateStateDatabaseReference = mFirebaseDatabase.getReference()
.child(constant.FIREBASE_CAR).child(constant.FIREBASE_START_STATE);
lightsStateDatabaseReference = mFirebaseDatabase.getReference()
.child(constant.FIREBASE_CAR).child(constant.FIREBASE_LIGHTS_STATE);
lockStateDatabaseReference = mFirebaseDatabase.getReference()
.child(constant.FIREBASE_CAR).child(constant.FIREBASE_LOCK_STATE);
mappingServicesDatabaseReference = mFirebaseDatabase.getReference()
.child(constant.FIREBASE_CAR).child(constant.FIREBASE_MAPPING_SERVICES);
sensorsValuesDatabaseReference = mFirebaseDatabase.getReference()
.child(constant.FIREBASE_CAR).child(constant.FIREBASE_SENSORES_VALUES);
connectionStateDatabaseReference.setValue(1);
}
//show Snackbar if there is no internet net connection
else {
if (carFragment != null) {
// Snackbar snackbar = Snackbar.make(carFragment, R.string.no_internet_connection, Snackbar.LENGTH_LONG);
// snackbar.show();
}
}
//get the date from the connected thread
bluetoothHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
//if message is what we want
if (msg.what == handlerState) {
// msg.arg1 = bytes from connect thread
String readMessage = (String) msg.obj;
//keep appending to string until ~ char
recDataString.append(readMessage);
//determine the end of the line
endOfLineIndex = recDataString.indexOf("~");
if (fragmentIsRunning) {
refreshUI();
}
}
}
};
//setup ans start the threads
potThread = new Thread(new PotProgressThread());
tempThread = new Thread(new TemperatureProgressThread());
ldrThread = new Thread(new LdrProgressThread());
fragmentIsRunning = true;
potThread.start();
tempThread.start();
ldrThread.start();
//set the buttons listener
lightsButton.setOnClickListener(this);
lockButton.setOnClickListener(this);
disconnectButton.setOnClickListener(this);
startButton.setOnClickListener(this);
//setup the map fragment
MapFragment mapFragment = (MapFragment) getActivity().getFragmentManager().findFragmentById(R.id.my_location_fragment_car);
mapFragment.getMapAsync(this);
// Inflate the layout for this fragment
return rootView;
}
Here is the code on onDestoryview() method
fragmentIsRunning = false;
potThread.interrupt();
how can i kill it
Dalvik keeps all Thread references in the runtime so your thread will keep running unless it is terminated or completes (some reference ). So depending on where you start your thread, you may be creating more than one.
In your case Your thread execution is not completed and you change the fragment so your getActivity()
will be null.
The solution is before getActivity()
, check isAdded()
is true or not, if not true, that means the fragment is already detached, call to getActivity()
will return null.
Remember in the Thread, everywhere before you call getActivity()
, you'd better to check isAdded() again, because user may exit the activity at anytime during the Thread is executing.
Other Solution
I am not sure but you can achieve by initialize Context
globally and you that context in your thread.
Context mContext;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
mContext = getActivity();
....
}
Now use this context in your thread.
class PotProgressThread implements Runnable {
@Override
public void run() {
while (potSensorValue <= 1025 && fragmentIsRunning) {
if (fragmentIsRunning) {
// Update the progress bar
potProgressBarHandler.post(new Runnable() {
public void run() {
potProgressBar.setProgress((int) potSensorValue);
if (potSensorValue >= 800) {
potProgressBar.setProgressDrawable(mContext.
getResources().getDrawable(R.drawable.progressbarred));
} else {
potProgressBar.setProgressDrawable(mContext.
getResources().getDrawable(R.drawable.progressbarblue));
}
}
});
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
break;
}
}
}
}
I hope you will get the solution.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.