2017-04-13 148 views
0

我无法理解这个问题。该行总是返回null,这会导致应用程序崩溃。该行是:为什么findFragmentById总是返回null

FragmentManager manager = activity.getFragmentManager(); 
DeviceListFragment fragment = (DeviceListFragment) 
manager.findFragmentById(R.id.frag_list); 
fragment.updateThisDevice((WifiP2pDevice) intent.getParcelableExtra(
       WifiP2pManager.EXTRA_WIFI_P2P_DEVICE)); 

片段为空。更好地了解情况。我有这个两个活动

首先是P2P活动

package it.linup.maint.activity; 

import android.app.Activity; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.net.wifi.p2p.WifiP2pConfig; 
import android.net.wifi.p2p.WifiP2pDevice; 
import android.net.wifi.p2p.WifiP2pManager; 
import android.net.wifi.p2p.WifiP2pManager.*; 


import android.os.Bundle; 

import android.view.Menu; 
import android.view.MenuInflater; 
import android.view.MenuItem; 
import android.view.View; 
import android.widget.Toast; 

import com.github.hiteshsondhi88.sampleffmpeg.R; 



public class P2P extends Activity implements ChannelListener, 
DeviceListFragment.DeviceActionListener { 

public static final String TAG = "wifidirectdemo"; 
private WifiP2pManager manager; 
private boolean isWifiP2pEnabled = false; 
private boolean retryChannel = false; 

private final IntentFilter intentFilter = new IntentFilter(); 
private WifiP2pManager.Channel channel; 
private BroadcastReceiver receiver = null; 

/** 
* @param isWifiP2pEnabled the isWifiP2pEnabled to set 
*/ 
public void setIsWifiP2pEnabled(boolean isWifiP2pEnabled) { 
    this.isWifiP2pEnabled = isWifiP2pEnabled; 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    // add necessary intent values to be matched. 

    intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION); 
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); 

intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION); 
    intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); 

    manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE); 
    channel = manager.initialize(this, getMainLooper(), null); 

} 

/** register the BroadcastReceiver with the intent values to be matched */ 
@Override 
public void onResume() { 
    super.onResume(); 
    receiver = new WiFiDirectBroadcastReceiver(manager, channel, this); 
    registerReceiver(receiver, intentFilter); 
} 

@Override 
public void onPause() { 
    super.onPause(); 
    unregisterReceiver(receiver); 
} 

/** 
* Remove all peers and clear all fields. This is called on 
* BroadcastReceiver receiving a state change event. 
*/ 
public void resetData() { 
    DeviceListFragment fragmentList = (DeviceListFragment) getFragmentManager() 
      .findFragmentById(R.id.frag_list); 
    DeviceDetailFragment fragmentDetails = (DeviceDetailFragment) getFragmentManager() 
      .findFragmentById(R.id.frag_detail); 
    if (fragmentList != null) { 
     fragmentList.clearPeers(); 
    } 
    if (fragmentDetails != null) { 
     fragmentDetails.resetViews(); 
    } 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    MenuInflater inflater = getMenuInflater(); 
    inflater.inflate(R.menu.action_items, menu); 
    return true; 
} 

/* 
* (non-Javadoc) 
* @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem) 
*/ 
@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
     case R.id.atn_direct_enable: 
      if (manager != null && channel != null) { 

       // Since this is the system wireless settings activity, it's 
       // not going to send us a result. We will be notified by 
       // WiFiDeviceBroadcastReceiver instead. 

       startActivity(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS)); 
      } else { 
       android.util.Log.e(TAG, "channel or manager is null"); 
      } 
      return true; 

     case R.id.atn_direct_discover: 
      if (!isWifiP2pEnabled) { 
       Toast.makeText(P2P.this, R.string.p2p_off_warning, 
         Toast.LENGTH_SHORT).show(); 
       return true; 
      } 
      final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager() 
        .findFragmentById(R.id.frag_list); 
      fragment.onInitiateDiscovery(); 
      manager.discoverPeers(channel, new WifiP2pManager.ActionListener() { 

       @Override 
       public void onSuccess() { 
        Toast.makeText(P2P.this, "Discovery Initiated", 
          Toast.LENGTH_SHORT).show(); 
       } 

       @Override 
       public void onFailure(int reasonCode) { 
        Toast.makeText(P2P.this, "Discovery Failed : " + reasonCode, 
          Toast.LENGTH_SHORT).show(); 
       } 
      }); 
      return true; 
     default: 
      return super.onOptionsItemSelected(item); 
    } 
} 

@Override 
public void showDetails(WifiP2pDevice device) { 
    DeviceDetailFragment fragment = (DeviceDetailFragment) getFragmentManager() 
      .findFragmentById(R.id.frag_detail); 
    fragment.showDetails(device); 

} 

@Override 
public void connect(WifiP2pConfig config) { 
    manager.connect(channel, config, new WifiP2pManager.ActionListener() { 

     @Override 
     public void onSuccess() { 
      // WiFiDirectBroadcastReceiver will notify us. Ignore for now. 
     } 

     @Override 
     public void onFailure(int reason) { 
      Toast.makeText(P2P.this, "Connect failed. Retry.", 
        Toast.LENGTH_SHORT).show(); 
     } 
    }); 
} 

@Override 
public void disconnect() { 
    final DeviceDetailFragment fragment = (DeviceDetailFragment) getFragmentManager() 
      .findFragmentById(R.id.frag_detail); 
    fragment.resetViews(); 
    manager.removeGroup(channel, new WifiP2pManager.ActionListener() { 

     @Override 
     public void onFailure(int reasonCode) { 
      android.util.Log.d(TAG, "Disconnect failed. Reason :" + reasonCode); 

     } 

     @Override 
     public void onSuccess() { 
      fragment.getView().setVisibility(View.GONE); 
     } 

    }); 
} 

@Override 
public void onChannelDisconnected() { 
    // we will try once more 
    if (manager != null && !retryChannel) { 
     Toast.makeText(this, "Channel lost. Trying again", Toast.LENGTH_LONG).show(); 
     resetData(); 
     retryChannel = true; 
     manager.initialize(this, getMainLooper(), this); 
    } else { 
     Toast.makeText(this, 
       "Severe! Channel is probably lost premanently. Try Disable/Re-Enable P2P.", 
       Toast.LENGTH_LONG).show(); 
    } 
} 

@Override 
public void cancelDisconnect() { 

    /* 
    * A cancel abort request by user. Disconnect i.e. removeGroup if 
    * already connected. Else, request WifiP2pManager to abort the ongoing 
    * request 
    */ 
    if (manager != null) { 
     final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager() 
       .findFragmentById(R.id.frag_list); 
     if (fragment.getDevice() == null 
       || fragment.getDevice().status == WifiP2pDevice.CONNECTED) { 
      disconnect(); 
     } else if (fragment.getDevice().status == WifiP2pDevice.AVAILABLE 
       || fragment.getDevice().status == WifiP2pDevice.INVITED) { 

      manager.cancelConnect(channel, new WifiP2pManager.ActionListener() { 

       @Override 
       public void onSuccess() { 
        Toast.makeText(P2P.this, "Aborting connection", 
          Toast.LENGTH_SHORT).show(); 
       } 

       @Override 
       public void onFailure(int reasonCode) { 
        Toast.makeText(P2P.this, 
          "Connect abort request failed. Reason Code: " + reasonCode, 
          Toast.LENGTH_SHORT).show(); 
       } 
      }); 
     } 
    } 

    } 
} 

第二activy是广播接收器,这是错误的是

WiFiDirectBroadcastReceiver

package it.linup.maint.activity; 

import android.app.FragmentManager; 
import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.net.NetworkInfo; 
import android.net.wifi.p2p.WifiP2pDevice; 
import android.net.wifi.p2p.WifiP2pManager; 


import com.github.hiteshsondhi88.sampleffmpeg.R; 



public class WiFiDirectBroadcastReceiver extends BroadcastReceiver { 

private WifiP2pManager manager; 
private WifiP2pManager.Channel channel; 
private P2P activity; 

/** 
* @param manager WifiP2pManager system service 
* @param channel Wifi p2p channel 
* @param activity activity associated with the receiver 
*/ 
public WiFiDirectBroadcastReceiver(WifiP2pManager manager, WifiP2pManager.Channel channel, 
            P2P activity) { 
    super(); 
    this.manager = manager; 
    this.channel = channel; 
    this.activity = activity; 
} 

/* 
* (non-Javadoc) 
* @see android.content.BroadcastReceiver#onReceive(android.content.Context, 
* android.content.Intent) 
*/ 
@Override 
public void onReceive(Context context, Intent intent) { 
    String action = intent.getAction(); 
    if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) { 

     // UI update to indicate wifi p2p status. 
     int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1); 
     if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) { 
      // Wifi Direct mode is enabled 
      activity.setIsWifiP2pEnabled(true); 
     } else { 
      activity.setIsWifiP2pEnabled(false); 
      activity.resetData(); 

     } 
     android.util.Log.d(P2P.TAG, "P2P state changed - " + state); 
    } else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) { 

     // request available peers from the wifi p2p manager. This is an 
     // asynchronous call and the calling activity is notified with a 
     // callback on PeerListListener.onPeersAvailable() 
     if (manager != null) { 
      manager.requestPeers(channel, (WifiP2pManager.PeerListListener) activity.getFragmentManager() 
        .findFragmentById(R.id.frag_list)); 
     } 
     android.util.Log.d(P2P.TAG, "P2P peers changed"); 
    } else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) { 

     if (manager == null) { 
      return; 
     } 

     NetworkInfo networkInfo = (NetworkInfo) intent 
       .getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO); 

     if (networkInfo.isConnected()) { 

      // we are connected with the other device, request connection 
      // info to find group owner IP 

      DeviceDetailFragment fragment = (DeviceDetailFragment) activity 
        .getFragmentManager().findFragmentById(R.id.frag_detail); 
      manager.requestConnectionInfo(channel, fragment); 
     } else { 
      // It's a disconnect 
      activity.resetData(); 
     } 
    } else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) { 

     FragmentManager manager = activity.getFragmentManager(); 

     DeviceListFragment fragment = (DeviceListFragment) manager.findFragmentById(R.id.frag_list); 
     fragment.updateThisDevice((WifiP2pDevice) intent.getParcelableExtra(
       WifiP2pManager.EXTRA_WIFI_P2P_DEVICE)); 

    } 
} 
} 

的P2P活动被称为在tabhost活动内部

Main活动

package it.linup.maint.activity; 

import android.app.TabActivity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MenuInflater; 
import android.view.MenuItem; 
import android.widget.TabHost; 

import com.github.hiteshsondhi88.libffmpeg.FFmpeg; 
import com.github.hiteshsondhi88.sampleffmpeg.R; 


public class Main extends TabActivity 
{ 




/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) 
{ 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 


    // create the TabHost that will contain the Tabs 
    TabHost tabHost = (TabHost)findViewById(android.R.id.tabhost); 


    TabHost.TabSpec tab1 = tabHost.newTabSpec("Home"); 
    TabHost.TabSpec tab2 = tabHost.newTabSpec("Log"); 
    //TabHost.TabSpec tab3 = tabHost.newTabSpec("Debug"); 
    TabHost.TabSpec tab4 = tabHost.newTabSpec("P2P"); 




    // Set the Tab name and Activity 
    // that will be opened when particular Tab will be selected 
    tab1.setIndicator("Home"); 
    tab1.setContent(new Intent(this, Home.class)); 

    tab2.setIndicator("Log"); 
    tab2.setContent(new Intent(this, Log.class)); 

    //tab3.setIndicator("Debug"); 
    //tab3.setContent(new Intent(this, DebugActivity.class)); 

    tab4.setIndicator("P2P"); 
    tab4.setContent(new Intent(this, P2P.class)); 







    /** Add the tabs to the TabHost to display. */ 
    tabHost.addTab(tab1); 
    tabHost.addTab(tab2); 
    tabHost.addTab(tab4); 
    //tabHost.addTab(tab3); 



    tabHost.setCurrentTab(1); 
    // tabHost.setCurrentTab(2); 
    tabHost.setCurrentTab(3); 
    tabHost.setCurrentTab(0); 

} 
public boolean onCreateOptionsMenu(Menu menu) { 
    MenuInflater inflater = getMenuInflater(); 
    inflater.inflate(R.menu.options_menu, menu); 
    return true; 
} 

public boolean onOptionsItemSelected(MenuItem item) { 

    switch (item.getItemId()) { 
     case R.id.settings: 
      startActivity(new Intent(this, Settings.class)); 
      return true; 
     case R.id.help: 
      startActivity(new Intent(this, Help.class)); 
      return true; 
     default: 
      return super.onOptionsItemSelected(item); 
    } 

} 

public void setText(String text) 
{ 
    Log activity = (Log) getLocalActivityManager().getActivity("Log"); 
    activity.refreshContent(text); 
} 

public FFmpeg getFfmpeg() 
{ 
    Home home = (Home) getLocalActivityManager().getActivity("Home"); 
    return home.getFfmpeg(); 
} 


} 

日志错误是:

FATAL EXCEPTION: main 
       Process: com.github.hiteshsondhi88.sampleffmpeg, PID: 25845 
       java.lang.RuntimeException: Error receiving broadcast Intent { act=android.net.wifi.p2p.THIS_DEVICE_CHANGED flg=0x4000010 (has extras) } in [email protected] 
        at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:979) 
        at android.os.Handler.handleCallback(Handler.java:743) 
        at android.os.Handler.dispatchMessage(Handler.java:95) 
        at android.os.Looper.loop(Looper.java:150) 
        at android.app.ActivityThread.main(ActivityThread.java:5665) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:822) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:712) 
       Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void it.linup.maint.activity.DeviceListFragment.updateThisDevice(android.net.wifi.p2p.WifiP2pDevice)' on a null object reference 
        at it.linup.maint.activity.WiFiDirectBroadcastReceiver.onReceive(WiFiDirectBroadcastReceiver.java:94) 
        at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:969) 
        at android.os.Handler.handleCallback(Handler.java:743)  
        at android.os.Handler.dispatchMessage(Handler.java:95)  
        at android.os.Looper.loop(Looper.java:150)  
        at android.app.ActivityThread.main(ActivityThread.java:5665)  
        at java.lang.reflect.Method.invoke(Native Method)  
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:822)  
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:712)  

我不明白为什么我得到这个错误。

+0

'第二个activity是一个BroadcastReceiver''Activity'绝对不是'BroadcastReceiver'。我也看不到你用你的ID添加一个片段。这就是你没有通过id找到它的原因 - 你不告诉系统它有这个ID。 –

回答

0

在片段交易过程中,您没有添加您的带有ID的片段,可以通过id或tag添加,然后通过id或tag找到。这就是它无法找到你的片段,因此返回null导致异常的原因。

+0

好吧..我很愚蠢......我用setContentView(R.layout.main)设置了错误的资源;谢谢大家 – elgeko

0

我想这是因为你没有添加任何与该ID的片段。你的经理不会创建你的片段,你必须告诉他哪个片段有这个ID。

相关问题