【发布时间】:2017-04-30 12:47:39
【问题描述】:
我的第一个主要应用程序再次造成严重破坏。 我的主要活动上有一个 tabLayout,用于在 3 个片段之间轻松切换。这是他们的标签
-“IP信息”
-“网络扫描”
-“实用程序”...
自从我 3 个月前开始这项活动以来,我的片段就出现了奇怪的行为。最大的问题是,首次启动活动时,我的片段中没有任何内容出现。这是一个空白页。我必须切换到另一个活动,然后一次或多次返回主要活动才能显示我的内容。对我来说,空白片段的实例似乎不规则,我无法追踪为它抛出的可靠错误。
这是我的整个主要活动,如果有什么事情发生的话:
public class MainActivity extends AppCompatActivity
implements devicesFragment.OnListFragmentInteractionListener,
IPInfoFragment.OnFragmentInteractionListener,
ToolsSelectionFragment.OnFragmentInteractionListener
{
public SectionsPagerAdapter mSectionsPagerAdapter;
public ViewPager mViewPager;
private SharedPreferences myprefs;
private SharedPreferences.Editor editor;
private final String PREFS_NAME = "userPrefs";
private MyDevice mydev;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mydev = new MyDevice(this);
new MyDeviceWorker().execute();
myprefs = getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
editor = myprefs.edit();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment fors each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
}
public void setActionBarTitle(String title){
getSupportActionBar().setTitle(title);
}
//region ACTIONBAR
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main2, 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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
//clear shared-preferences
editor.clear();
Intent logoutIntent = new Intent(MainActivity.this, LoginActivity.class);
finish();
startActivity(logoutIntent);
}
if (id == R.id.action_profile) {
Intent intent = new Intent(this, ProfileActivity.class);
startActivity(intent);
}
return super.onOptionsItemSelected(item);
}
@Override
public void onListFragmentInteraction(Devices device) {
}
//endregion
//region ASYNCTASK_RUNNERS
private class MyDeviceWorker extends AsyncTask {
@Override
protected Object doInBackground(Object[] params) {
mydev.setListNetworkInterfaces();
mydev.setInterfacesByDisplayName();
mydev.getSSIDName();
mydev.getLocalAddresses("wlan0");
return this;
}
}
//endregion
@Override
public void onFragmentInteraction(String title) {
}
@Override
public void onFragmentInteraction(Uri uri) {
}
//endregion
//region PAGE ADAPTER
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
switch (position) {
case 0:
Parcelable wrapped = Parcels.wrap(mydev);
return IPInfoFragment.newInstance(position + 1, wrapped);
case 1:
return devicesFragment.newInstance(position);
case 2:
return ToolsSelectionFragment.newInstance(position + 1);
default:
Parcelable wrappeddefault = Parcels.wrap(mydev);
return IPInfoFragment.newInstance(position + 1, wrappeddefault);
}
}
@Override
public int getCount() {
// Show 3 total pages.
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return getText(R.string.title_fragment_IPINFO);
case 1:
return getText(R.string.title_fragment_NETSCAN);
case 2:
return getText(R.string.title_fragment_UTILITIES);
}
return null;
}
}
//endregion
}
方法:public Fragment getItem(int position) {} 是片段的膨胀。
和我的片段示例都类似地膨胀:
public ToolsSelectionFragment() {
// Required empty public constructor
}
public static ToolsSelectionFragment newInstance(int sectionNumber) {
ToolsSelectionFragment fragment = new ToolsSelectionFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_tools_selection,container, false);
initvar(v);
registerButtonListeners();
return v;
}
如果格式关闭,我们深表歉意。只是希望有人对我的问题有意见。
*********更新********* 由于缺乏解析,这是我的片段的完整代码
IPInfo 片段:
public class IPInfoFragment extends Fragment implements Serializable, myResultReceiver.Receiver {
//region UI VARS
TextView tvStatus;
TextView tvPrivateIP;
TextView tvPrivateMAC;
TextView tvConnectionStatus;
TextView tvSSID;
TextView tvNetMask;
TextView tvFrequency;
TextView tvSignal;
TextView tvBroadcast;
TextView tvBSSID;
TextView tvNetIP;
//endregion
public myResultReceiver mReceiver;
public DatabaseHelper dbhelper;
public static String PrivateIP;
public static String PrivateMAC;
public MyDevice mydev;
public Network mynet;
public MyNet personalNet;
public User currentUser;
public final String PREFS_NAME = "userPrefs";
public SharedPreferences myprefs;
public SharedPreferences.Editor editor;
//region FRAGMENT STUFF
private OnFragmentInteractionListener mListener;
private static final String ARG_SECTION_NUMBER = "section_number";
private static final String MYDEV_KEY = "MyDevices_Key";
public IPInfoFragment() {
// Required empty public constructor
}
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static IPInfoFragment newInstance(int sectionNumber, Parcelable wrappedDev) {
IPInfoFragment fragment = new IPInfoFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
args.putParcelable(MYDEV_KEY, wrappedDev);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_ipinfo, container, false);
((MainActivity) getActivity()).setActionBarTitle("IP Info");
//keep track of current user
myprefs = getActivity().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
currentUser = new User(myprefs.getString("USERNAME_KEY", "---"), myprefs.getString("EMAIL_KEY", "---"), myprefs.getString("USERPASS_KEY", "---"));
mydev = Parcels.unwrap(getArguments().getParcelable(MYDEV_KEY));
new MyDeviceWorker().execute();
launchNetworkSniffer(1);
ViewPager mViewPager = (ViewPager) v.findViewById(R.id.container);
PrivateIP = mydev.getIp();
PrivateMAC = mydev.getMac();
initVar(v);
return v;
}
public void launchNetworkSniffer(int opr) {
Intent serviceIntent = new Intent(getActivity(), NetHelper.class);
//setup resultReceiver for service callbacks
mReceiver = new myResultReceiver(new android.os.Handler());
mReceiver.setReceiver(this);
serviceIntent.putExtra(NetHelper.BUNDLE_RECEIVER2, mReceiver);
serviceIntent.putExtra("OPR", opr);
getActivity().startService(serviceIntent);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context; }
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
//region ASYNCTASK_RUNNERS
private class MyDeviceWorker extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
Log.d("BACKGROUND_STARTED", "doing background stufffss**********(^*%fsdf");
mydev.setListNetworkInterfaces();
mydev.setInterfacesByDisplayName();
mydev.getSSIDName();
mydev.getLocalAddresses("wlan0");
return null;
}
@Override
protected void onPostExecute(Void v) {
tvPrivateIP.setText(mydev.getIp().toString());
tvPrivateMAC.setText(mydev.getMac().toString());
}
}
//endregion
@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
Log.d("NET_DATA_RECEIVED", "processing...");
String newnetjson = resultData.getString("DATA_");
Log.d("DATA_", newnetjson);
Gson gson = new Gson();
mynet = gson.fromJson(newnetjson, Network.class);
//region DATABASE WORK
//confusing naming conventions but whatever, It's crunch time.
personalNet = new MyNet(currentUser.getName(), mynet.getSSID(), mynet.getBSSID(), mynet.getSignal(), mynet.getFrequency(), mynet.getNetIP(), mynet.getBroadcast(), mynet.getNetMask());
new Thread(new Runnable() {
@Override
public void run() {
dbhelper = new DatabaseHelper(getActivity().getApplicationContext());
//if returns true, a record exists - so just update teh times connected counter
if (dbhelper.checkNetworkHistory(currentUser.getName(), mynet.getSSID())) {
Log.d("DB_IPINFO_OP", "updating user history record for this network");
dbhelper.updateNetCounter(personalNet);
}
else {
Log.d("DB_IPINFO_OP", "adding new network to user history");
dbhelper.addUserNetwork(personalNet);
}
}
}).start();
//region FILL UI
if (mynet.getState()) { tvConnectionStatus.setText("Connected."); }
else { tvConnectionStatus.setText("Disconnected"); }
tvSSID.setText(mynet.getSSID());
tvBroadcast.setText(mynet.getBroadcast());
if (mynet.getFrequency() == 0) { tvFrequency.setText("----"); }
else { tvFrequency.setText(String.valueOf(mynet.getFrequency())); }
tvBSSID.setText(mynet.getBSSID());
tvNetIP.setText(mynet.getNetIP());
if (mynet.getNetMask() == 0) { tvNetMask.setText("----"); }
else { tvNetMask.setText(String.valueOf(mynet.getNetMask())); }
if (mynet.getSignal() == 0) { tvSignal.setText("----"); }
else { tvSignal.setText(String.valueOf(mynet.getSignal())); }
//endregion
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(String title);
}
//endregion
public void initVar(View v) {
tvPrivateIP = (TextView) v.findViewById(R.id.tvPersonalIP);
tvPrivateMAC = (TextView) v.findViewById(R.id.tvPersonalMAC);
tvConnectionStatus = (TextView) v.findViewById(R.id.lblisConnected);
tvSSID = (TextView) v.findViewById(R.id.tvSSID);
tvBSSID = (TextView) v.findViewById(R.id.tvBSSID);
tvNetMask = (TextView) v.findViewById(R.id.tvNetMask);
tvFrequency = (TextView) v.findViewById(R.id.tvFrequency);
tvSignal = (TextView) v.findViewById(R.id.tvSignal);
tvBroadcast = (TextView) v.findViewById(R.id.tvBroadCast);
tvNetIP = (TextView) v.findViewById(R.id.tvNetIP);
tvPrivateIP.setText(PrivateIP);
tvPrivateMAC.setText(PrivateMAC);
}
//region INET-STUFF
//gets ipv6
public String getLocalIpAddress()
{
try
{
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();)
{
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();)
{
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress())
{
return inetAddress.getHostAddress().toString();
}
}
}
}
catch (SocketException ex)
{
Log.e("SRM", ex.toString());
}
return null;
}
//endregion
}
ToolsSelection 片段
public class ToolsSelectionFragment extends Fragment {
//region UI VARS
Button btnPing;
Button btnDns;
Button btnPortScan;
Button btnTraceRoute;
//endregion
private static final String ARG_SECTION_NUMBER = "section_number";
private OnFragmentInteractionListener mListener;
public ToolsSelectionFragment() {
// Required empty public constructor
}
public static ToolsSelectionFragment newInstance(int sectionNumber) {
ToolsSelectionFragment fragment = new ToolsSelectionFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_tools_selection, container, false);
initvar(v);
registerButtonListeners();
return v;
}
public void initvar(View view) {
btnPing = (Button) view.findViewById(R.id.btnPing);
btnDns = (Button) view.findViewById(R.id.btnDns);
btnPortScan = (Button) view.findViewById(R.id.btnPortScan);
btnTraceRoute = (Button) view.findViewById(R.id.btnTraceRoute);
}
public void registerButtonListeners() {
btnPing.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), PingActivity.class);
startActivity(intent);
}
});
btnDns.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), DNSActivity.class);
startActivity(intent);
}
});
btnPortScan.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), PortscanActivity.class);
startActivity(intent);
}
});
btnTraceRoute.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), WhoisActivity.class);
startActivity(intent);
}
});
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
DevicesFragment:
public class devicesFragment extends Fragment implements myResultReceiver.Receiver {
public myResultReceiver mReceiver;
OnListFragmentInteractionListener mlistener;
Context context;
MydevicesRecyclerViewAdapter mydevAdapter;
private static ArrayList<Devices> devlist;
SharedPreferences netprefs;
// TODO: Customize parameter argument names
private static final String ARG_COLUMN_COUNT = "column-count";
private int mColumnCount = 1;
private OnListFragmentInteractionListener mListener;
public devicesFragment() {
}
// TODO: Customize parameter initialization
public static devicesFragment newInstance(int columnCount) {
devicesFragment fragment = new devicesFragment();
Bundle args = new Bundle();
args.putInt(ARG_COLUMN_COUNT, columnCount);
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mColumnCount = getArguments().getInt(ARG_COLUMN_COUNT);
}
}
//TODO: populate devices list with a sharedPreferences list and double check there. also split up subnet into multiple threads to work faster.
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_devices_list, container, false);
((MainActivity) getActivity()).setActionBarTitle("Net Scan");
devlist = new ArrayList<>();
devlist.add(new Devices("TEST_DEVICE", true, "192.168.100.199", "00:00:00:00:00:00", true, "MOBILE", "meeseeks box"));
devlist.add(new Devices("TEST_DEVICE2", true, "74.16.248.777", "11:11:11:11:11:11", true, "DESKTOP", "meeseeks box"));
launchNetworkSniffer(0);
// Set the adapter
if (view instanceof RecyclerView) {
Context context = view.getContext();
RecyclerView recyclerView = (RecyclerView) view;
if (mColumnCount <= 1) {
recyclerView.setLayoutManager(new LinearLayoutManager(context));
} else {
recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
}
mydevAdapter = new MydevicesRecyclerViewAdapter(devlist, mListener);
recyclerView.setAdapter(mydevAdapter);
}
return view;
}
//NetHelper intent service class startup
//discover network info, and get a list of devices
public void launchNetworkSniffer(int opr) {
Intent serviceIntent = new Intent(getActivity(), NetHelper.class);
//setup resultReceiver for service callbacks
mReceiver = new myResultReceiver(new android.os.Handler());
mReceiver.setReceiver(this);
serviceIntent.putExtra(NetHelper.BUNDLE_RECEIVER, mReceiver);
serviceIntent.putExtra("OPR", opr);
getActivity().startService(serviceIntent);
}
@Override
public void onResume() {
super.onResume();
mReceiver.setReceiver(this);
}
//avoid leaks with result receiver
@Override
public void onPause() {
super.onPause();
mReceiver.setReceiver(null);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mlistener = (OnListFragmentInteractionListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement listener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
//receiver implemented methods
@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
Log.d("DATA_RECEIVED", "processing...");
String newdevjson = resultData.getString("DATA_");
Log.d("DATA_", newdevjson);
Gson gson = new Gson();
Devices newd = gson.fromJson(newdevjson, Devices.class);
if (devlist != null) {
for (Devices i : devlist) {
if (i.getIp().equals(newd.getIp())) {
return;
}
}
Log.d("ADDING_FRAGDEVICE", newd.devName);
devlist.add(newd);
mydevAdapter.notifyItemInserted(devlist.size() -1);
mydevAdapter.notifyDataSetChanged();
}
}
public interface OnListFragmentInteractionListener {
// TODO: Update argument type and name
void onListFragmentInteraction(Devices device);
}
}
真的希望尽快解决这个问题。 感谢迄今为止尝试过的人。
【问题讨论】:
-
你在片段之间传递值吗?
-
是的,通过 Parceler 我将一个对象传递给一个片段,否则通过 sharedPreferences 跟踪数据。
-
您正在将值传递给片段,但没有接收到片段。您需要从片段的 oncreate 方法中获取值..
-
分享片段的完整代码
-
我正在从我的活动中调用的 newInstance 方法中检索我的值。 *查看我的最后一个代码段。 args.putInt 是我从 parcelable 中检索值的地方。尽管如此,这并不能解释所有 3 个片段的行为。我根本不将值传递给我的片段之一。
标签: java android android-viewpager fragment