从一个活动片段到另一个活动的意图给出了java.lang.IllegalArgumentException:Android中没有针对类错误的注射器工厂绑定

时间:2018-07-03 07:41:10

标签: java android android-fragments dependency-injection butterknife

我对Android有一定的了解,但是我对Fragments,Injection,Binding,ButterKnife等不熟悉。我已经看过一些视频和教程,但无法发现问题所在。

我想做什么

我从GitHub存储库中获得了此活动和代码( MeshInteractionActivity.java )。我要创建另一个活动 MainActivity.java ,并在按下按钮时连接到此“网格活动”。我认为从MainActivity到MeshInteractionActivity做一个Intent会很简单。但这没有用。我觉得可能需要在MainActivity上添加一个片段,用于第二个活动,因此我创建了 MainFragment.java 。我在MainFragment上得到了2个按钮,但是当我按下网格按钮(即 MainFragment 中的mesh()方法)时,应用程序崩溃了。

我尝试学习ButterKnife并看了一些视频,但是它们太基础了,我不知道它们如何适合我的用例。由于我的代码包含以下部分:

@Inject
DispatchingAndroidInjector<Fragment> mDispatchingAndroidInjector;

@Inject
ViewModelProvider.Factory mViewModelFactory;

我还不了解的东西。

我收到的错误

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.mrinq.mesh_ha_v01/com.mrinq.mesh_ha_v01.MeshInteractionActivity}: java.lang.IllegalArgumentException: No injector factory bound for Class<com.mrinq.mesh_ha_v01.MeshInteractionActivity>
    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.IllegalArgumentException: No injector factory bound for Class<com.mrinq.mesh_ha_v01.MeshInteractionActivity>
    at dagger.android.DispatchingAndroidInjector.inject(DispatchingAndroidInjector.java:106)
    at dagger.android.AndroidInjection.inject(AndroidInjection.java:61)
    at com.mrinq.mesh_ha_v01.di.AppInjector.handleActivity(AppInjector.java:88)
    at com.mrinq.mesh_ha_v01.di.AppInjector.access$000(AppInjector.java:39)
    at com.mrinq.mesh_ha_v01.di.AppInjector$1.onActivityCreated(AppInjector.java:51)
    at android.app.Application.dispatchActivityCreated(Application.java:195)
    at android.app.Activity.onCreate(Activity.java:926)
    at android.support.v4.app.SupportActivity.onCreate(SupportActivity.java:66)
    at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:321)
    at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:84)
    at com.mrinq.mesh_ha_v01.MeshInteractionActivity.onCreate(MeshInteractionActivity.java:87)
    at android.app.Activity.performCreate(Activity.java:6259)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1130)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
    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)

我的源活动是 MainActivity.java

public class MainActivity extends AppCompatActivity implements Injectable,
    HasSupportFragmentInjector,
    BottomNavigationView.OnNavigationItemSelectedListener,
    BottomNavigationView.OnNavigationItemReselectedListener,
    ScannerFragment.ScannerFragmentListener, FragmentManager.OnBackStackChangedListener,
    NetworkFragment.NetworkFragmentListener,
    MainFragment.MainFragmentListener,
    DialogFragmentResetNetwork.DialogFragmentResetNetworkListener {

private static final String TAG = MainActivity.class.getSimpleName();
private static final String CURRENT_FRAGMENT = "CURRENT_FRAGMENT";

@Inject
DispatchingAndroidInjector<Fragment> mDispatchingAndroidInjector;

@Inject
ViewModelProvider.Factory mViewModelFactory;

@BindView(R.id.state_scanning)
View mScanningView;

private SharedViewModel mViewModel;
private BottomNavigationView mBottomNavigationView;

private NetworkFragment mNetworkFragment;
private ScannerFragment mScannerFragment;
private MainFragment mMainFragment;
private Fragment mSettingsFragment;

@Override
protected void onCreate(@Nullable final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);

    final Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setTitle(R.string.app_name);

    mViewModel = ViewModelProviders.of(this, mViewModelFactory).get(SharedViewModel.class);

    mNetworkFragment = (NetworkFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_network);
    mScannerFragment = (ScannerFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_scanner);
    mSettingsFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_settings);
    mMainFragment = (MainFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_main);
    mBottomNavigationView = findViewById(R.id.bottom_navigation_view);

    mBottomNavigationView.setOnNavigationItemSelectedListener(this);
    mBottomNavigationView.setOnNavigationItemReselectedListener(this);

    mViewModel.getProvisionedNodesLiveData().observe(this, provisionedNodesLiveData -> {
        invalidateOptionsMenu();
    });

    mViewModel.isConnected().observe(this, isConnected -> {
        if(isConnected != null) {
            invalidateOptionsMenu();
        }
    });

    if(savedInstanceState == null) {
        onNavigationItemSelected(mBottomNavigationView.getMenu().findItem(R.id.action_network));
    } else {
        mBottomNavigationView.setSelectedItemId(savedInstanceState.getInt(CURRENT_FRAGMENT));
    }

}

@Override
public boolean onCreateOptionsMenu(final Menu menu) {
    if(!mViewModel.getProvisionedNodesLiveData().getProvisionedNodes().isEmpty()){
        if(mNetworkFragment.isVisible()) {
            if (!mViewModel.isConenctedToMesh()) {
                getMenuInflater().inflate(R.menu.connect, menu);
            } else {
                getMenuInflater().inflate(R.menu.disconnect, menu);
            }
        } else if(mSettingsFragment.isVisible()){
            getMenuInflater().inflate(R.menu.reset_network, menu);
        } else {
            return false;
        }
    } else {
        return false;
    }
    return true;
}

@Override
public boolean onOptionsItemSelected(final MenuItem item) {
    final int id = item.getItemId();
    switch (id) {
        case R.id.action_connect:
            final Intent scannerActivity = new Intent(this, ProvisionedNodesScannerActivity.class);
            scannerActivity.putExtra(ProvisionedNodesScannerActivity.NETWORK_ID, mViewModel.getNetworkId());
            startActivity(scannerActivity);
            return true;
        case R.id.action_disconnect:
            mViewModel.disconnect();
            return true;
        case R.id.action_reset_network:
            final DialogFragmentResetNetwork dialogFragmentResetNetwork = DialogFragmentResetNetwork.
                    newInstance(getString(R.string.title_reset_network), getString(R.string.message_reset_network));
            dialogFragmentResetNetwork.show(getSupportFragmentManager(), null);
            return true;
    }
    return false;
}

@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == Utils.PROVISIONING_SUCCESS){
        if(resultCode == RESULT_OK){
            final boolean result = data.getBooleanExtra("result", false);
            if(result){
                mBottomNavigationView.setSelectedItemId(R.id.action_network);
            }
        }
    }
}

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
    final int id = item.getItemId();
    final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    switch (id) {
        case R.id.action_network:
            ft.hide(mNetworkFragment).hide(mScannerFragment).hide(mSettingsFragment).show(mMainFragment);
            break;
        case R.id.action_scanner:
            ft.hide(mNetworkFragment).hide(mScannerFragment).hide(mSettingsFragment).show(mMainFragment);
            break;
        case R.id.action_settings:
            ft.hide(mNetworkFragment).hide(mScannerFragment).hide(mSettingsFragment).show(mMainFragment);
            break;
    }
    ft.commit();
    invalidateOptionsMenu();
    return true;
}

@Override
public void onNavigationItemReselected(@NonNull MenuItem item) {
}

@Override
public void showProgressBar() {
    mScanningView.setVisibility(View.INVISIBLE);
}

@Override
public void hideProgressBar() {
    mScanningView.setVisibility(View.INVISIBLE);
}

@Override
public void onBackStackChanged() {

}

@Override
public AndroidInjector<Fragment> supportFragmentInjector() {
    return mDispatchingAndroidInjector;
}

@Override
public void onProvisionedMeshNodeSelected() {

}

@Override
public void onNetworkReset() {
    mViewModel.resetMeshNetwork();
}  }

MainActivity 夸大的源片段是 MainFragment.java

/**
* A simple {@link Fragment} subclass.
* Activities that contain this fragment must implement the
* {@link MainFragment.OnFragmentInteractionListener} interface
* to handle interaction events.
* Use the {@link MainFragment#newInstance} factory method to
* create an instance of this fragment.
*/
public class MainFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";

// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;

/*private OnFragmentInteractionListener mListener;*/
private MainFragmentListener mMainFragmentListener;

BleMeshManager instBleMeshManager;

@BindView(R.id.send) Button sendButton;
@BindView(R.id.mesh) Button meshButton;
private Unbinder unbinder;

@OnClick(R.id.send)
public void send() {
    instBleMeshManager.sendPdu(new byte[] {0x01, 0x02, 0x03, 0x04});
}

@OnClick(R.id.mesh)
public void mesh() {
    Intent meshActivityIntent = new Intent(getActivity(), MeshInteractionActivity.class);
    startActivity(meshActivityIntent);
}

public MainFragment() {
    // Required empty public constructor
}

/**
 * Use this factory method to create a new instance of
 * this fragment using the provided parameters.
 *
 * @param param1 Parameter 1.
 * @param param2 Parameter 2.
 * @return A new instance of fragment MainFragment.
 */
// TODO: Rename and change types and number of parameters
public static MainFragment newInstance(String param1, String param2) {
    MainFragment fragment = new MainFragment();
    Bundle args = new Bundle();
    args.putString(ARG_PARAM1, param1);
    args.putString(ARG_PARAM2, param2);
    fragment.setArguments(args);
    return fragment;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getArguments() != null) {
        mParam1 = getArguments().getString(ARG_PARAM1);
        mParam2 = getArguments().getString(ARG_PARAM2);
    }

    instBleMeshManager = new BleMeshManager(getActivity());

    //onButtonPressed();

}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_main, container, false);
    ButterKnife.bind(this, view);

    // Inflate the layout for this fragment
    return view;
}

// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(/*Uri uri*/) {
    if (mMainFragmentListener != null) {
        mMainFragmentListener.hideProgressBar(/*uri*/);
    }
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof MainFragmentListener) {
        mMainFragmentListener = (MainFragmentListener) context;
    } else {
        throw new RuntimeException(context.toString()
                + " must implement OnFragmentInteractionListener");
    }
}

@Override
public void onDetach() {
    super.onDetach();
    mMainFragmentListener = null;
}

/*@Override
public void onDestroyView() {
    super.onDestroyView();
    unbinder.unbind();
}*/

/**
 * 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*//*);
}*/
public interface MainFragmentListener {
    void showProgressBar();
    void hideProgressBar();
}
}

MainActivity的Intent跳转到的我的目标Activity是 MeshInteractionActivity

public class MeshInteractionActivity extends AppCompatActivity implements Injectable, HasSupportFragmentInjector,  BottomNavigationView.OnNavigationItemSelectedListener,
    BottomNavigationView.OnNavigationItemReselectedListener,
    ScannerFragment.ScannerFragmentListener, FragmentManager.OnBackStackChangedListener,
    NetworkFragment.NetworkFragmentListener,
    DialogFragmentResetNetwork.DialogFragmentResetNetworkListener {

private static final String TAG = MeshInteractionActivity.class.getSimpleName();
private static final String CURRENT_FRAGMENT = "CURRENT_FRAGMENT";

@Inject
DispatchingAndroidInjector<Fragment> mDispatchingAndroidInjector;

@Inject
ViewModelProvider.Factory mViewModelFactory;

@BindView(R.id.state_scanning)
View mScanningView;

private SharedViewModel mViewModel;
private BottomNavigationView mBottomNavigationView;

private NetworkFragment mNetworkFragment;
private ScannerFragment mScannerFragment;
private Fragment mSettingsFragment;

@Override
protected void onCreate(@Nullable final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_mesh_interaction);
    ButterKnife.bind(this);

    final Toolbar toolbar = findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setTitle(R.string.app_name);

    mViewModel = ViewModelProviders.of(this, mViewModelFactory).get(SharedViewModel.class);

    mNetworkFragment = (NetworkFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_network);
    mScannerFragment = (ScannerFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_scanner);
    mSettingsFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_settings);
    mBottomNavigationView = findViewById(R.id.bottom_navigation_view);

    mBottomNavigationView.setOnNavigationItemSelectedListener(this);
    mBottomNavigationView.setOnNavigationItemReselectedListener(this);

    mViewModel.getProvisionedNodesLiveData().observe(this, provisionedNodesLiveData -> {
        invalidateOptionsMenu();
    });

    mViewModel.isConnected().observe(this, isConnected -> {
        if(isConnected != null) {
            invalidateOptionsMenu();
        }
    });

    if(savedInstanceState == null) {
        onNavigationItemSelected(mBottomNavigationView.getMenu().findItem(R.id.action_network));
    } else {
        mBottomNavigationView.setSelectedItemId(savedInstanceState.getInt(CURRENT_FRAGMENT));
    }

}

@Override
public void onBackPressed() {
    super.onBackPressed();
    Intent mainActivityIntent = new Intent(MeshInteractionActivity.this, MainActivity.class);
    startActivity(mainActivityIntent);

}

@Override
public boolean onCreateOptionsMenu(final Menu menu) {
    if(!mViewModel.getProvisionedNodesLiveData().getProvisionedNodes().isEmpty()){
        if(mNetworkFragment.isVisible()) {
            if (!mViewModel.isConenctedToMesh()) {
                getMenuInflater().inflate(R.menu.connect, menu);
            } else {
                getMenuInflater().inflate(R.menu.disconnect, menu);
            }
        } else if(mSettingsFragment.isVisible()){
            getMenuInflater().inflate(R.menu.reset_network, menu);
        } else {
            return false;
        }
    } else {
        return false;
    }
    return true;
}

@Override
public boolean onOptionsItemSelected(final MenuItem item) {
    final int id = item.getItemId();
    switch (id) {
        case R.id.action_connect:
            final Intent scannerActivity = new Intent(this, ProvisionedNodesScannerActivity.class);
            scannerActivity.putExtra(ProvisionedNodesScannerActivity.NETWORK_ID, mViewModel.getNetworkId());
            startActivity(scannerActivity);
            return true;
        case R.id.action_disconnect:
            mViewModel.disconnect();
            return true;
        case R.id.action_reset_network:
            final DialogFragmentResetNetwork dialogFragmentResetNetwork = DialogFragmentResetNetwork.
                    newInstance(getString(R.string.title_reset_network), getString(R.string.message_reset_network));
            dialogFragmentResetNetwork.show(getSupportFragmentManager(), null);
            return true;
    }
    return false;
}

@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == Utils.PROVISIONING_SUCCESS){
        if(resultCode == RESULT_OK){
            final boolean result = data.getBooleanExtra("result", false);
            if(result){
                mBottomNavigationView.setSelectedItemId(R.id.action_network);
            }
        }
    }
}

@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
    final int id = item.getItemId();
    final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
    switch (id) {
        case R.id.action_network:
            ft.show(mNetworkFragment).hide(mScannerFragment).hide(mSettingsFragment);
            break;
        case R.id.action_scanner:
            ft.hide(mNetworkFragment).show(mScannerFragment).hide(mSettingsFragment);
            break;
        case R.id.action_settings:
            ft.hide(mNetworkFragment).hide(mScannerFragment).show(mSettingsFragment);
            break;
    }
    ft.commit();
    invalidateOptionsMenu();
    return true;
}

@Override
public void onNavigationItemReselected(@NonNull MenuItem item) {
}

@Override
public void showProgressBar() {
    mScanningView.setVisibility(View.VISIBLE);
}

@Override
public void hideProgressBar() {
    mScanningView.setVisibility(View.INVISIBLE);
}

@Override
public void onBackStackChanged() {

}

@Override
public AndroidInjector<Fragment> supportFragmentInjector() {
    return mDispatchingAndroidInjector;
}

@Override
public void onProvisionedMeshNodeSelected() {

}

@Override
public void onNetworkReset() {
    mViewModel.resetMeshNetwork();
}
}

该活动也有自己的片段,但我想问题是从第一个活动片段的意图跳到了第二个活动。

谢谢。

0 个答案:

没有答案