从片段调用 Activity 方法时出现 NullPointerException,成为 ClassCastException
NullPointerException when calling an Activity method from a fragment, became a ClassCastException
这是我第一次遇到这个错误,老实说,在阅读了这里的 nullpointerexception 线程后,我仍然不太理解它。根据我的搜索,当某些内容指向 null 并导致错误时,就会发生这种情况。我不确定我的代码哪里错了。
错误
03-31 21:40:34.841 31029-31029/com.sti.ravago.researchlayout E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.sti.ravago.researchlayout, PID: 31029
java.lang.NullPointerException
at com.sti.ravago.researchlayout.MainActivity.redirect(MainActivity.java:70)
at com.sti.ravago.researchlayout.ListFragment.onClick(ListFragment.java:93)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:169)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
at dalvik.system.NativeStart.main(Native Method)
主要Activity
public class MainActivity extends AppCompatActivity implements BottomNavigationView.OnNavigationItemSelectedListener {
private final Fragment mTimerFragment = new TimerFragment();
private final Fragment mListFragment = new ListFragment();
private final Fragment mReminderFragment = new RemindFragment();
private final TimerFragment timeFrag = (TimerFragment)getSupportFragmentManager().findFragmentByTag("TimerFragment");
private Fragment mActiveFragment = mTimerFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager().beginTransaction()
.add(R.id.fragContainer, mReminderFragment, "TimerFragment")
.hide(mReminderFragment)
.commit();
getSupportFragmentManager().beginTransaction()
.add(R.id.fragContainer, mListFragment, "ListFragment")
.hide(mListFragment)
.commit();
getSupportFragmentManager().beginTransaction()
.add(R.id.fragContainer, mTimerFragment, "ReminderFragment")
.commit();
BottomNavigationView navigation = findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(this);
}
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
getSupportFragmentManager().beginTransaction()
.hide(mActiveFragment)
.show(mTimerFragment)
.commit();
mActiveFragment = mTimerFragment;
return true;
case R.id.navigation_dashboard:
getSupportFragmentManager().beginTransaction()
.hide(mActiveFragment)
.show(mListFragment)
.commit();
mActiveFragment = mListFragment;
return true;
case R.id.navigation_notifications:
getSupportFragmentManager().beginTransaction()
.hide(mActiveFragment)
.show(mReminderFragment)
.commit();
mActiveFragment = mReminderFragment;
return true;
}
return false;
}
public void redirect(String app) {
timeFrag.startTime(app);
// Toast.makeText(this, "Test", Toast.LENGTH_SHORT).show();
// Toast.makeText(this, app, Toast.LENGTH_SHORT).show();
}
}
这个只是切换片段,以及调用片段的方法activity。
列表Activity
public class ListFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag_list,null);
ListView list1 = view.findViewById(R.id.listview1);
ActivityManager am = (ActivityManager)getActivity().getSystemService(Context.ACTIVITY_SERVICE);
PackageManager packageManager = getActivity().getPackageManager();
ArrayAdapter<String> aa;
List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfo = am.getRunningAppProcesses();
final String pnArr[] = new String[runningAppProcessInfo.size()];
List<String> filteredApps = new ArrayList<>();
final List<String> filteredRunningApps = new ArrayList<>();
final List<String> appNames = new ArrayList<>();
//user-apps loop
List<PackageInfo> apps = getActivity().getPackageManager().getInstalledPackages(0);
for (int i = 0; i < apps.size(); i++){
if ((apps.get(i).applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 1){
filteredApps.add(apps.get(i).packageName);
}
}
//running apps + comparison loop
for (int i = 0; i < runningAppProcessInfo.size(); i++) {
pnArr[i] = runningAppProcessInfo.get(i).processName;
if (filteredApps.contains(runningAppProcessInfo.get(i).processName)) {
filteredRunningApps.add(runningAppProcessInfo.get(i).processName);
}
}
//package name -> app name conversion
for (int i = 0; i < filteredRunningApps.size();i++) {
ApplicationInfo ai = null;
try{
ai = packageManager.getApplicationInfo(filteredRunningApps.get(i),0);
}catch (PackageManager.NameNotFoundException e){}
String title = (String)((ai != null) ? packageManager.getApplicationLabel(ai) : "???");
appNames.add(title);
}
Toast.makeText(getActivity(), "Filtered Apps : " + filteredApps.size() + " | Running Apps : " + runningAppProcessInfo.size() + " | Filtered Running Apps : " + filteredRunningApps.size(), Toast.LENGTH_LONG).show();
ArrayList<String> pnList = new ArrayList<String>();
pnList.addAll(Arrays.asList(pnArr));
aa = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,appNames);
list1.setAdapter(aa);
aa.notifyDataSetChanged();
final MainActivity mA = (MainActivity)getActivity();
list1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
AlertDialog.Builder adb = new AlertDialog.Builder(getActivity());
adb.setTitle("Monitor " + appNames.get(position) + "?");
adb.setMessage("Track this application's usage time?");
adb.setPositiveButton("YES", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String app = appNames.get(position);
Toast.makeText(getActivity(), "Currently monitoring " + appNames.get(position) + ".", Toast.LENGTH_SHORT).show();
((MainActivity) getActivity()).redirect(app);
}
});
adb.setNegativeButton("NO", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//Toast.makeText(getActivity(), "test", Toast.LENGTH_SHORT).show();
}
});
adb.show();
}
});
return view;
}
}
它说我在MainActivity的第70行和ListFragment的第93行有错误,指向这个
timeFrag.startTime(app);
和
((MainActivity) getActivity()).redirect(app);
如果非要我猜的话,是 startTime
和 redirect
指向 null,但它们是如何指向 null 的,我该如何修复它?
更新
所以我将片段声明移到了方法中,它不再是 NullPointerException。现在是 ClassCastException。
04-01 05:51:17.520 31117-31117/com.sti.ravago.researchlayout E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.sti.ravago.researchlayout, PID: 31117
java.lang.ClassCastException: com.sti.ravago.researchlayout.RemindFragment cannot be cast to com.sti.ravago.researchlayout.TimerFragment
at com.sti.ravago.researchlayout.MainActivity.redirect(MainActivity.java:69)
at com.sti.ravago.researchlayout.ListFragment.onClick(ListFragment.java:93)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:169)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
at dalvik.system.NativeStart.main(Native Method)
这真的很奇怪,因为我没有任何调用 RemindFragment 的代码,除了 MainActivity。 MainActivity 代码可以在上面找到,唯一的变化是我将一个片段声明移到了一个方法中以避免 NullPointerException。这是 TimerFragment 和 RemindFragment 的代码,尽管我认为它们在这种情况下并不重要,但由于在错误中提到了它们,我认为它们可能会发挥作用,但老实说我不知道。
提醒片段
package com.sti.ravago.researchlayout;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class RemindFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag_remind,null);
return view;
}
}
TimerFragment
public class TimerFragment extends Fragment {
Button btnMonitor;
Button btnRemind;
TimePicker tp;
CountDownTimer cdt;
TextView tvTimer, tvRemind;
long startTime = 0;
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
@Override
public void run() {
long millis = System.currentTimeMillis() - startTime;
int seconds = (int)(millis/1000);
int minutes = seconds / 60;
seconds = seconds % 60;
tvTimer.setText(String.format("%d:%02d", minutes, seconds));
timerHandler.postDelayed(this,500);
}
};
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag_timer, null);
tp = (TimePicker)view.findViewById(R.id.timepick1);
tvTimer = (TextView)view.findViewById(R.id.tvTimer);
tvRemind = view.findViewById(R.id.textView3);
btnMonitor = (Button)view.findViewById(R.id.btn1);
btnRemind = (Button)view.findViewById(R.id.btn2);
btnRemind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Calendar cal = Calendar.getInstance();
//current
Date c = cal.getTime();
long currentTime = c.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy h:mm a");
//String d = sdf.format(c); //output 27/03/2019 3:05 AM
//timepicker time
String tpTime = String.valueOf(tp.getCurrentHour()) +":"+ String.valueOf(tp.getCurrentMinute());
int tpDateDay = cal.get(Calendar.DAY_OF_MONTH);
int tpDateMonth = cal.get(Calendar.MONTH);
int tpDateYear = cal.get(Calendar.YEAR);
Calendar c2 = Calendar.getInstance();
c2.set(tpDateYear,tpDateMonth,tpDateDay,tp.getCurrentHour(),tp.getCurrentMinute(),0);
long tpMillis = c2.getTimeInMillis();
long remaining = tpMillis - currentTime;
Toast.makeText(getActivity(),"Remaining time "+ remaining/1000, Toast.LENGTH_SHORT).show();
cdt = new CountDownTimer(remaining,1000) {
@Override
public void onTick(long millisUntilFinished) {
tvRemind.setText(" " + millisUntilFinished/1000 + " seconds");
}
@Override
public void onFinish() {
Intent intent = new Intent (getActivity(),MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(getActivity(),(int)System.currentTimeMillis(),intent,0);
Notification n = new Notification.Builder(getActivity())
.setContentTitle("Time is up!")
.setContentText("Consider stopping the application now.")
.setSmallIcon(R.drawable.ic_notifications_black_24dp)
.setContentIntent(pIntent)
.setAutoCancel(true)
.build();
NotificationManager nm = (NotificationManager)getActivity().getSystemService(getActivity().NOTIFICATION_SERVICE);
nm.notify(0,n);
tvRemind.setText("0");
}
}.start();
}
});
btnMonitor.setText("Start");
btnMonitor.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Button b = (Button) v;
if (b.getText().equals("Stop")){
timerHandler.removeCallbacks(timerRunnable);
b.setText("Start Monitoring");
}
else {
startTime = System.currentTimeMillis();
timerHandler.postDelayed(timerRunnable, 0);
b.setText("Stop");
Toast.makeText(getActivity(),"Monitoring started.",Toast.LENGTH_SHORT).show();
}
}
});
return view;
}
public void startTime(String app) {
btnMonitor.performClick();
Toast.makeText(getActivity(), "Monitoring for " + app + " started." , Toast.LENGTH_LONG).show();
}
}
错误指向这些行
final TimerFragment timeFrag = (TimerFragment)getSupportFragmentManager().findFragmentByTag("TimerFragment");
这很奇怪,因为我把它放在 redirect
方法中来解决 NullPointerException。
((MainActivity) getActivity()).redirect(app);
不知道这里出了什么问题。
我该如何解决这个问题?
private final TimerFragment timeFrag = (TimerFragment)getSupportFragmentManager().findFragmentByTag("TimerFragment");
您在创建 Activity
时调用它,这意味着您的 Fragment
将不存在。把这段代码移到你需要使用的地方:
void redirect(String app) {
final TimerFragment timeFrag = (TimerFragment)getSupportFragmentManager().findFragmentByTag("TimerFragment");
if(timeFrag != null) timeFrag.startTime(app);
}
这是我第一次遇到这个错误,老实说,在阅读了这里的 nullpointerexception 线程后,我仍然不太理解它。根据我的搜索,当某些内容指向 null 并导致错误时,就会发生这种情况。我不确定我的代码哪里错了。
错误
03-31 21:40:34.841 31029-31029/com.sti.ravago.researchlayout E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.sti.ravago.researchlayout, PID: 31029
java.lang.NullPointerException
at com.sti.ravago.researchlayout.MainActivity.redirect(MainActivity.java:70)
at com.sti.ravago.researchlayout.ListFragment.onClick(ListFragment.java:93)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:169)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
at dalvik.system.NativeStart.main(Native Method)
主要Activity
public class MainActivity extends AppCompatActivity implements BottomNavigationView.OnNavigationItemSelectedListener {
private final Fragment mTimerFragment = new TimerFragment();
private final Fragment mListFragment = new ListFragment();
private final Fragment mReminderFragment = new RemindFragment();
private final TimerFragment timeFrag = (TimerFragment)getSupportFragmentManager().findFragmentByTag("TimerFragment");
private Fragment mActiveFragment = mTimerFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager().beginTransaction()
.add(R.id.fragContainer, mReminderFragment, "TimerFragment")
.hide(mReminderFragment)
.commit();
getSupportFragmentManager().beginTransaction()
.add(R.id.fragContainer, mListFragment, "ListFragment")
.hide(mListFragment)
.commit();
getSupportFragmentManager().beginTransaction()
.add(R.id.fragContainer, mTimerFragment, "ReminderFragment")
.commit();
BottomNavigationView navigation = findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(this);
}
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
getSupportFragmentManager().beginTransaction()
.hide(mActiveFragment)
.show(mTimerFragment)
.commit();
mActiveFragment = mTimerFragment;
return true;
case R.id.navigation_dashboard:
getSupportFragmentManager().beginTransaction()
.hide(mActiveFragment)
.show(mListFragment)
.commit();
mActiveFragment = mListFragment;
return true;
case R.id.navigation_notifications:
getSupportFragmentManager().beginTransaction()
.hide(mActiveFragment)
.show(mReminderFragment)
.commit();
mActiveFragment = mReminderFragment;
return true;
}
return false;
}
public void redirect(String app) {
timeFrag.startTime(app);
// Toast.makeText(this, "Test", Toast.LENGTH_SHORT).show();
// Toast.makeText(this, app, Toast.LENGTH_SHORT).show();
}
}
这个只是切换片段,以及调用片段的方法activity。
列表Activity
public class ListFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag_list,null);
ListView list1 = view.findViewById(R.id.listview1);
ActivityManager am = (ActivityManager)getActivity().getSystemService(Context.ACTIVITY_SERVICE);
PackageManager packageManager = getActivity().getPackageManager();
ArrayAdapter<String> aa;
List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfo = am.getRunningAppProcesses();
final String pnArr[] = new String[runningAppProcessInfo.size()];
List<String> filteredApps = new ArrayList<>();
final List<String> filteredRunningApps = new ArrayList<>();
final List<String> appNames = new ArrayList<>();
//user-apps loop
List<PackageInfo> apps = getActivity().getPackageManager().getInstalledPackages(0);
for (int i = 0; i < apps.size(); i++){
if ((apps.get(i).applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 1){
filteredApps.add(apps.get(i).packageName);
}
}
//running apps + comparison loop
for (int i = 0; i < runningAppProcessInfo.size(); i++) {
pnArr[i] = runningAppProcessInfo.get(i).processName;
if (filteredApps.contains(runningAppProcessInfo.get(i).processName)) {
filteredRunningApps.add(runningAppProcessInfo.get(i).processName);
}
}
//package name -> app name conversion
for (int i = 0; i < filteredRunningApps.size();i++) {
ApplicationInfo ai = null;
try{
ai = packageManager.getApplicationInfo(filteredRunningApps.get(i),0);
}catch (PackageManager.NameNotFoundException e){}
String title = (String)((ai != null) ? packageManager.getApplicationLabel(ai) : "???");
appNames.add(title);
}
Toast.makeText(getActivity(), "Filtered Apps : " + filteredApps.size() + " | Running Apps : " + runningAppProcessInfo.size() + " | Filtered Running Apps : " + filteredRunningApps.size(), Toast.LENGTH_LONG).show();
ArrayList<String> pnList = new ArrayList<String>();
pnList.addAll(Arrays.asList(pnArr));
aa = new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1,appNames);
list1.setAdapter(aa);
aa.notifyDataSetChanged();
final MainActivity mA = (MainActivity)getActivity();
list1.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
AlertDialog.Builder adb = new AlertDialog.Builder(getActivity());
adb.setTitle("Monitor " + appNames.get(position) + "?");
adb.setMessage("Track this application's usage time?");
adb.setPositiveButton("YES", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String app = appNames.get(position);
Toast.makeText(getActivity(), "Currently monitoring " + appNames.get(position) + ".", Toast.LENGTH_SHORT).show();
((MainActivity) getActivity()).redirect(app);
}
});
adb.setNegativeButton("NO", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//Toast.makeText(getActivity(), "test", Toast.LENGTH_SHORT).show();
}
});
adb.show();
}
});
return view;
}
}
它说我在MainActivity的第70行和ListFragment的第93行有错误,指向这个
timeFrag.startTime(app);
和
((MainActivity) getActivity()).redirect(app);
如果非要我猜的话,是 startTime
和 redirect
指向 null,但它们是如何指向 null 的,我该如何修复它?
更新
所以我将片段声明移到了方法中,它不再是 NullPointerException。现在是 ClassCastException。
04-01 05:51:17.520 31117-31117/com.sti.ravago.researchlayout E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.sti.ravago.researchlayout, PID: 31117
java.lang.ClassCastException: com.sti.ravago.researchlayout.RemindFragment cannot be cast to com.sti.ravago.researchlayout.TimerFragment
at com.sti.ravago.researchlayout.MainActivity.redirect(MainActivity.java:69)
at com.sti.ravago.researchlayout.ListFragment.onClick(ListFragment.java:93)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:169)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
at dalvik.system.NativeStart.main(Native Method)
这真的很奇怪,因为我没有任何调用 RemindFragment 的代码,除了 MainActivity。 MainActivity 代码可以在上面找到,唯一的变化是我将一个片段声明移到了一个方法中以避免 NullPointerException。这是 TimerFragment 和 RemindFragment 的代码,尽管我认为它们在这种情况下并不重要,但由于在错误中提到了它们,我认为它们可能会发挥作用,但老实说我不知道。
提醒片段
package com.sti.ravago.researchlayout;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class RemindFragment extends Fragment {
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag_remind,null);
return view;
}
}
TimerFragment
public class TimerFragment extends Fragment {
Button btnMonitor;
Button btnRemind;
TimePicker tp;
CountDownTimer cdt;
TextView tvTimer, tvRemind;
long startTime = 0;
Handler timerHandler = new Handler();
Runnable timerRunnable = new Runnable() {
@Override
public void run() {
long millis = System.currentTimeMillis() - startTime;
int seconds = (int)(millis/1000);
int minutes = seconds / 60;
seconds = seconds % 60;
tvTimer.setText(String.format("%d:%02d", minutes, seconds));
timerHandler.postDelayed(this,500);
}
};
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag_timer, null);
tp = (TimePicker)view.findViewById(R.id.timepick1);
tvTimer = (TextView)view.findViewById(R.id.tvTimer);
tvRemind = view.findViewById(R.id.textView3);
btnMonitor = (Button)view.findViewById(R.id.btn1);
btnRemind = (Button)view.findViewById(R.id.btn2);
btnRemind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Calendar cal = Calendar.getInstance();
//current
Date c = cal.getTime();
long currentTime = c.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy h:mm a");
//String d = sdf.format(c); //output 27/03/2019 3:05 AM
//timepicker time
String tpTime = String.valueOf(tp.getCurrentHour()) +":"+ String.valueOf(tp.getCurrentMinute());
int tpDateDay = cal.get(Calendar.DAY_OF_MONTH);
int tpDateMonth = cal.get(Calendar.MONTH);
int tpDateYear = cal.get(Calendar.YEAR);
Calendar c2 = Calendar.getInstance();
c2.set(tpDateYear,tpDateMonth,tpDateDay,tp.getCurrentHour(),tp.getCurrentMinute(),0);
long tpMillis = c2.getTimeInMillis();
long remaining = tpMillis - currentTime;
Toast.makeText(getActivity(),"Remaining time "+ remaining/1000, Toast.LENGTH_SHORT).show();
cdt = new CountDownTimer(remaining,1000) {
@Override
public void onTick(long millisUntilFinished) {
tvRemind.setText(" " + millisUntilFinished/1000 + " seconds");
}
@Override
public void onFinish() {
Intent intent = new Intent (getActivity(),MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(getActivity(),(int)System.currentTimeMillis(),intent,0);
Notification n = new Notification.Builder(getActivity())
.setContentTitle("Time is up!")
.setContentText("Consider stopping the application now.")
.setSmallIcon(R.drawable.ic_notifications_black_24dp)
.setContentIntent(pIntent)
.setAutoCancel(true)
.build();
NotificationManager nm = (NotificationManager)getActivity().getSystemService(getActivity().NOTIFICATION_SERVICE);
nm.notify(0,n);
tvRemind.setText("0");
}
}.start();
}
});
btnMonitor.setText("Start");
btnMonitor.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Button b = (Button) v;
if (b.getText().equals("Stop")){
timerHandler.removeCallbacks(timerRunnable);
b.setText("Start Monitoring");
}
else {
startTime = System.currentTimeMillis();
timerHandler.postDelayed(timerRunnable, 0);
b.setText("Stop");
Toast.makeText(getActivity(),"Monitoring started.",Toast.LENGTH_SHORT).show();
}
}
});
return view;
}
public void startTime(String app) {
btnMonitor.performClick();
Toast.makeText(getActivity(), "Monitoring for " + app + " started." , Toast.LENGTH_LONG).show();
}
}
错误指向这些行
final TimerFragment timeFrag = (TimerFragment)getSupportFragmentManager().findFragmentByTag("TimerFragment");
这很奇怪,因为我把它放在 redirect
方法中来解决 NullPointerException。
((MainActivity) getActivity()).redirect(app);
不知道这里出了什么问题。
我该如何解决这个问题?
private final TimerFragment timeFrag = (TimerFragment)getSupportFragmentManager().findFragmentByTag("TimerFragment");
您在创建 Activity
时调用它,这意味着您的 Fragment
将不存在。把这段代码移到你需要使用的地方:
void redirect(String app) {
final TimerFragment timeFrag = (TimerFragment)getSupportFragmentManager().findFragmentByTag("TimerFragment");
if(timeFrag != null) timeFrag.startTime(app);
}