0

I have this AsynTask class that works perfectly on an activity. I used a similar method in a new app that uses fragments because of tabs and it's failing me.

Below is the context menu item where I instantiate the class (OverviewFragment.java):

@Override
public boolean onContextItemSelected(MenuItem item){
    //AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
    //int position = info.position;

    super.onContextItemSelected(item);
    if(item.getTitle() == "Show Report"){

        Intent intent = new Intent();
        intent.setAction(android.content.Intent.ACTION_VIEW);
        File file = new File(Environment.getExternalStorageDirectory().getPath() + "/"  + this.getPDFFileName() + ".pdf");
        intent.setDataAndType(Uri.fromFile(file), "application/pdf");
        startActivity(intent);
    }

    if(item.getTitle()=="Upload report via webservice")
    {
        itemClicked = "uploadMain_file";

        uploadToERP uploadToERP = new uploadToERP(this.getActivity());
        uploadToERP.execute();

    }


    if(item.getTitle()=="Send as attachment")
    {

        this.sendMail(this.getPDFFileName());

    }
    if(item.getTitle()=="Upload to ERP")
    {

        itemClicked = "uploadMain_data";
        uploadToERP uploadToERP = new uploadToERP(getActivity());
        uploadToERP.execute();

    }

    return true;
}

And here is the class:

package com.application.sweetiean.stlmaintenance;

import android.content.Context;
import android.os.AsyncTask;
import android.widget.Toast;

import com.application.sweetiean.stlservicing.Serv_OverviewFragment;
import com.application.sweetiean.stlservicing.ServicingActivity;

/**
 * Created by sweetiean on 1/15/2016.
*/
public class uploadToERP extends AsyncTask<String, Integer, Void> {

Context context;
String file;
String Maintenance_Info;
String Task;
String Service_Info;
String Servicing;
String Replacement;

public uploadToERP(Context c){
    context = c;
}

@Override
protected Void doInBackground(String... params) {

    Boolean doNothing = false;

    try{


        if(OverviewFragment.itemClicked.equals("uploadMain_file")) {
            file = MaintenanceActivity.Main_axcall.SendMainFile(OverviewFragment.getBytesFromFile(), OverviewFragment.sysaidIdFileName + ".pdf");
            doNothing = true;
        }
        /*if(Serv_OverviewFragment.itemClicked.equals("uploadServ_file")) {
            file = ServicingActivity.Serv_axcall.SendServFile(Serv_OverviewFragment.getBytesFromFile(),Serv_OverviewFragment.sysaidIdFileName+".pdf");
            doNothing = true;
        }*/



        if(!doNothing) {
            //check info because you will be receiving from both info data
            MaintenanceAppDB getRecord = new MaintenanceAppDB(context);

            //since there are two modules using this class I will have to set itemclicked for all the context
            //menu items and use that check
            if(OverviewFragment.itemClicked.equals("uploadMain_data")) {
                Maintenance_Info = getRecord.getMaintenanceInfoRecord(OverviewFragment.sysaidIdFileName);

                Task = getRecord.getTaskRecord(OverviewFragment.sysaidIdFileName);
            }

            /*if(Serv_OverviewFragment.itemClicked.equals("uploadServ_data")) {
                Service_Info = getRecord.getServiceInfoRecord(Serv_OverviewFragment.sysaidIdFileName);
                Servicing = getRecord.getServicingRecord(Serv_OverviewFragment.sysaidIdFileName);
                Replacement = getRecord.getReplacementRecord(Serv_OverviewFragment.sysaidIdFileName);

            }*/
        }//end insert



    }catch (Exception e){


        e.printStackTrace();


    }

    return null;
}



@Override
protected void onPostExecute(Void aVoid) {

    if(OverviewFragment.itemClicked.equals("uploadMain_file")) {

        Toast.makeText(context, file, Toast.LENGTH_SHORT).show();

    }/*else if(Serv_OverviewFragment.itemClicked.equals("uploadServ_file")) {

        Toast.makeText(context, file, Toast.LENGTH_SHORT).show();

    }*/else if(OverviewFragment.itemClicked.equals("uploadMain_data")) {

        Toast.makeText(context, Maintenance_Info, Toast.LENGTH_SHORT).show();
        Toast.makeText(context, Task, Toast.LENGTH_SHORT).show();

    }/*else if(Serv_OverviewFragment.itemClicked.equals("uploadServ_data")) {

        Toast.makeText(context, Service_Info, Toast.LENGTH_SHORT).show();
        Toast.makeText(context, Servicing, Toast.LENGTH_SHORT).show();
        Toast.makeText(context, Replacement, Toast.LENGTH_SHORT).show();

    }*/

    Toast.makeText(context, "Upload to ERP complete!!!", Toast.LENGTH_LONG).show();

}



}

Any help will be deeply appreciated. I have read many other answers since last Friday and I still can't find a solution to my problem. The onPostExecute method works alright but the doInBackground method does not get called at all. I realised that when I was debugging.


After some much-needed motivation from Gavriel and David, I finally got the debugger to run through the doInbackground method. I commented out the second If statement as that particular class is not loaded at the time when the AsyncTask class is called(makes sense) Thank you David for making me look harder anyway so Gavriel, I finally got the debugger to run through that method and here is the error code I am getting now SoapFault - faultcode: 'soap:Server' faultstring: 'Server was unable to process request. ---> Value cannot be null. Parameter name: This method cannot be invoked because a required argument has not been supplied.' faultactor: 'null' detail: org.kxml2.kdom.Node@41e9cc30 on the line Maintenance_Info = getRecord.getMaintenanceInfoRecord(OverviewFragment.sysaidIdFileName); it's totally unrelated to my initial problem. I have to look to the methods in my db class and the webservice.java to figure out which required argument is returning null

Sweetie Anang
  • 332
  • 1
  • 3
  • 15
  • 1
    Any error log? It doesn't make sense that android calls onPostExec without calling doInBackground... Add breakpoint on the 1st line of doInBackground and debug it. – Gavriel Jan 28 '16 at 15:23
  • " it's failing me". How? can you show a LogCat? – David M Jan 28 '16 at 15:23
  • @Gavriel yes I was also thinking the same that it doesn't make sense and when I put a breakpoint there, the debugger doesn't even get there. This thing is acting weird. Very weird. – Sweetie Anang Jan 28 '16 at 15:31
  • @DavidM there is no visible error. But I will check again in a second and if there is one I am missing, I'll paste it here. – Sweetie Anang Jan 28 '16 at 15:32

2 Answers2

2

Update: I'm glad you found the line which throws the exception in doInBackground. I think fixing that will probably solve the problem.

General thoughts:

According to your code uploadToERP has to get a String as input:

uploadToERP extends AsyncTask<String, Integer, Void> 

but you haven't pass any:

uploadToERP uploadToERP = new uploadToERP(getActivity());
uploadToERP.execute(/* String is missing from here !!! */);

The 1st type of the triplet is the input type of doInBackground(), as you got it right. However someone has to pass the input to the AsyncTask. When you call execute, you have to pass the input value(s):

uploadToERP.execute("http://example.com");
uploadToERP.execute("http://example.com/1", "http://example.com/2", ...);

If you do not intend to use an input, then I suggest you to change it to:

uploadToERP extends AsyncTask<Void, Integer, Void> 

protected Void doInBackground(Void p...)
Gavriel
  • 18,880
  • 12
  • 68
  • 105
  • These inputs are the arguments for the methods implemented in the class. Not its "execute" method. Correct me if I am wrong but I have had this class work in the past and never passed any arguments to it. Moreover, I do not get a type error for that or any error but if I changed the types of the parameters for any of the implemented errors I get a type error example if I make the parameter type Void I will get an error because I specified it as a String `protected Void doInBackground(String... params)` – Sweetie Anang Jan 28 '16 at 16:20
  • I think you're wrong. See: http://stackoverflow.com/questions/9671546/asynctask-android-example but even better here: http://developer.android.com/reference/android/os/AsyncTask.html – Gavriel Jan 28 '16 at 16:23
  • `private class LongOperation extends AsyncTask` `protected String doInBackground(String... params) ` `protected void onProgressUpdate(Void... values) ` `protected void onPostExecute(String result)` I am making the point that the input parameters in the class declaration correspond the arguments used in the implemented methods so I do not see how this relates to the return type. That is why I don't understand why it .execute requires a parameter although I know it can accept a string parameter. – Sweetie Anang Jan 28 '16 at 17:09
  • Also from the google references (which I have read a lot this week); `private class DownloadFilesTask extends AsyncTask` `protected Long doInBackground(URL... urls)` `protected void onProgressUpdate(Integer... progress) ` `protected void onPostExecute(Long result)`. And this is how it is implemented ` new DownloadFilesTask().execute(url1, url2, url3);` Can you please explain your answer a bit more? – Sweetie Anang Jan 28 '16 at 17:12
  • Yes, the doInBackground error is all fixed now and the soapFault error is also fixed, I will post my answer referencing those. However, this topic of .execute() accepting parameters, I didn't use any parameters and it is all working fine after fixing the errors I was having. It is making me think the parameters for .execute() are not at all required even though the doInBackground is a String. I am still reading online resources because I still need to understand why and under which circumstances .execute() will require parameters. Thank you for your initial comment though it helped a lot. – Sweetie Anang Jan 29 '16 at 13:40
  • 1
    generally speaking they're needed to pass the input to the task, but you although declared tour AsyncTask to receive strings as input, you don't really use the input, that's why it doesn't matter in your case – Gavriel Jan 29 '16 at 13:44
0

The doInBackground method seemed not to be working because I was referencing a class which was not loaded at the time doInBackground is called:

if(Serv_OverviewFragment.itemClicked.equals("uploadServ_file")) {
        file = ServicingActivity.Serv_axcall.SendServFile(Serv_OverviewFragment.getBytesFromFile(),Serv_OverviewFragment.sysaidIdFileName+".pdf");
        doNothing = true;
    }

This makes perfect sense. I was trying to accomplish two tasks with one class but I have since deleted all references to the Serv_OverviewFragment from this class and created a new asyncTask for that purpose.

Now to my second error I was getting after this was fixed was caused as a result of the difference in parameter names in the android code and the c# code on the server side. So I have since compared and ensured the parameter names are all spelled the same and any case-sensitive issues resolved. Once again I want to show my appreciation to Gavriel and David for their comments which nudged me into the right direction :-)

Sweetie Anang
  • 332
  • 1
  • 3
  • 15