Odoo-mobile / framework

Odoo Mobile Framework
https://play.google.com/store/apps/dev?id=8607973775002477408
Other
327 stars 374 forks source link

Framework addon makes app crash (addon = hr.employee) #363

Open ichou96 opened 6 years ago

ichou96 commented 6 years ago

Hi, I am using the latest framework version. I tried to implement the procedure listed in the official documentation to add a new module (hr.employee). I followed every step as presented. Unfortunately I am getting a run-time error. Here is the log for the error:

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.odoo, PID: 15062 java.lang.NullPointerException: Attempt to invoke virtual method 'android.net.Uri com.odoo.core.orm.OModel.uri()' on a null object reference at com.odoo.addons.hr.Salary.onCreateLoader(Salary.java:89) at android.support.v4.app.LoaderManagerImpl.createLoader(LoaderManager.java:539) at android.support.v4.app.LoaderManagerImpl.createAndInstallLoader(LoaderManager.java:548) at android.support.v4.app.LoaderManagerImpl.initLoader(LoaderManager.java:603) at com.odoo.addons.hr.Salary.onViewCreated(Salary.java:79) at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1315) at android.support.v4.app.FragmentManagerImpl.moveFragmentsToInvisible(FragmentManager.java:2323) at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2136) at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2092) at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1998) at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:709) at android.os.Handler.handleCallback(Handler.java:751) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6692) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)

and here is the code for the provider, syncservice, models, main class and xml ressources: Salary.java

` public class Salary extends BaseFragment implements LoaderManager.LoaderCallbacks,ISyncStatusObserverListener, SwipeRefreshLayout.OnRefreshListener, OCursorListAdapter.OnViewBindListener {

public static final String TAG = Salary.class.getSimpleName();
private View mView;
private ListView listView;
private OCursorListAdapter listAdapter;

@Override
public List<ODrawerItem> drawerMenus(Context context) {
    List<ODrawerItem> items = new ArrayList<ODrawerItem>();
    items.add(new ODrawerItem(TAG).setTitle("Salaries").setIcon(R.drawable.ic_action_user).setInstance(new Salary()));
    return items;
}

@Override
public Class<HrSalary> database() {
    return HrSalary.class;
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    return inflater.inflate(R.layout.common_listview, container, false);
}

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    mView = view;
    listView = (ListView) mView.findViewById(R.id.listview);
    listAdapter = new OCursorListAdapter(getActivity(), null, android.R.layout.simple_list_item_1);
    listView.setAdapter(listAdapter);
    listAdapter.setOnViewBindListener(this);
    setHasSyncStatusObserver(TAG, this, db());
    getLoaderManager().initLoader(0, null, this);
}

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    if (db() == null) {
        Toast.makeText(getActivity(), "db null", Toast.LENGTH_SHORT).show();
        getLoaderManager().initLoader(0, null, this);
        return null;
    }
    return new CursorLoader(getActivity(), db().uri(), null, null, null, null);
}

@Override
public void onLoaderReset(Loader<Cursor> loader) {
    listAdapter.changeCursor(null);
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    listAdapter.changeCursor(data);
    if (data.getCount() > 0) {
        OControls.setGone(mView, R.id.loadingProgress);
        OControls.setVisible(mView, R.id.swipe_container);
        OControls.setGone(mView, R.id.data_list_no_item);
        setHasSwipeRefreshView(mView, R.id.swipe_container, this);
    } else {
        OControls.setGone(mView, R.id.loadingProgress);
        OControls.setGone(mView, R.id.swipe_container);
        OControls.setVisible(mView, R.id.data_list_no_item);
        setHasSwipeRefreshView(mView, R.id.data_list_no_item, this);
        OControls.setText(mView, R.id.title, "No Tasks found");
        OControls.setText(mView, R.id.subTitle, "Swipe to check new tasks");
    }
    if (db().isEmptyTable()) {
        // Request for sync
        onRefresh();
    }
}

@Override
public void onRefresh() {
    if (inNetwork()) {
        parent().sync().requestSync(HrSalary.AUTHORITY);
    } else{
        Toast.makeText(getActivity(), "no network access", Toast.LENGTH_SHORT).show();
    }
}

@Override
public void onStatusChange(Boolean refreshing) {
    if(refreshing){
        getLoaderManager().restartLoader(0, null, this);
    }
}

@Override
public void onViewBind(View view, Cursor cursor, ODataRow row) {
    OControls.setText(view, android.R.id.text1, row.getString("wage"));
}

} `

Models Employee.java and HrSalary.java

` public class Employee extends OModel { public static final String TAG = Employee.class.getSimpleName();

OColumn name = new OColumn("Name", OVarchar.class).setSize(100);
OColumn id = new OColumn("ID", OInteger.class);

public Employee(Context context, String model_name, OUser user) {
    super(context, "hr.employee", user);
}

} `

` public class HrSalary extends OModel { public static final String TAG = HrSalary.class.getSimpleName(); public static final String AUTHORITY = "com.odoo.addons.hr.salary";

OColumn employee_id = new OColumn("Employee", Employee.class, OColumn.RelationType.ManyToOne);
OColumn wage = new OColumn("Wage", OFloat.class);

public HrSalary(Context context, String model_name, OUser user) {
    super(context, "hr.contract", user);
}

@Override
public Uri uri(){
    return buildURI(AUTHORITY);
}

} `

SalaryProvider.java

` public class SalaryProvider extends BaseModelProvider { public static final String TAG = SalaryProvider.class.getSimpleName();

@Override
public String authority() {
    return HrSalary.AUTHORITY;
}

} `

SalarySyncService.java

` public class SalarySyncService extends OSyncService { public static final String TAG = SalarySyncService.class.getSimpleName();

@Override
public OSyncAdapter getSyncAdapter(OSyncService service, Context context) {
    return new OSyncAdapter(getApplicationContext(), HrSalary.class, this, true);
}

@Override
public void performDataSync(OSyncAdapter adapter, Bundle extras, OUser user) {
    adapter.syncDataLimit(80);
}

} `

salary_sync_adapter.xml

<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android" android:accountType="com.odoo.auth" android:contentAuthority="com.odoo.addons.hr.salary" android:supportsUploading="true" android:userVisible="true" />

additions in AndroidManifest.xml

` <service android:name="com.odoo.addons.hr.services.SalarySyncService" android:exported="true" android:process=":sync_tasks">

        <meta-data
            android:name="android.content.SyncAdapter"
            android:resource="@xml/salary_sync_adapter" />
    </service>
    <provider
        android:name="com.odoo.addons.hr.providers.SalaryProvider"
        android:authorities="com.odoo.addons.hr.salary"
        android:label="Salaries"
        android:multiprocess="true" />

`

I will be grateful if you can tell me what am I doing wrong. Thank you in advance.

naitikvithlani commented 6 years ago

Hello @ichou96 I had just quick view your code, i suggest to change the following:

1) Add line in onCreateView() setHasSyncStatusObserver(KEY, this, db());

2) Change interface which you had implemented LoaderManager.LoaderCallbacks<Cursor>

3) Change in onLoaderReset() mAdapter.changeCursor(null);

For more please check framework repository Customers.java class.