【问题标题】:Execute a function on the end of asynctask在 asynctask 结束时执行一个函数
【发布时间】:2017-07-08 05:08:42
【问题描述】:

我现在有一个小问题: 在我调用的异步任务完成后,我试图在我的片段上显示 2 个按钮。为此,我正在使用这个:

while (!recordi.getterminé){

    } 
    terminé();

但这不是最佳选择,我的应用没有响应 :( 那么有没有办法在 onPostExecute 函数中调用函数 terminé() 呢? 谢谢。

这是我的代码:

片段:

public class FragmentEnregistrer extends Fragment {

    String path,nomfinal, ip="http://MYIP/php";
    ImageButton mrecord,mupload,mlire;
    TextView Nomm;
    ProgressBar progressbar;
    int i=2;
    EnregistrerSon recordi;
    String id;


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View myView= inflater.inflate(R.layout.enregistrer, container, false);

        mrecord= (ImageButton) myView.findViewById(record);
        mupload= (ImageButton) myView.findViewById(upload);
        mlire= (ImageButton) myView.findViewById(lire);
        Nomm = (TextView) myView.findViewById(NomWhizz);
        progressbar = (ProgressBar) myView.findViewById(progressBar);
        progressbar.setVisibility(View.INVISIBLE);

        id=((MainActivity)getActivity()).getIdentifiant();

        mrecord.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.N)
            @Override
            public void onClick(View v) {
                Toast.makeText(getActivity().getApplicationContext(), "Enregistrement en cours", Toast.LENGTH_SHORT).show();
                String nomm = Nomm.getText().toString();
                nomm=nomm.replace(" ", "_");
                nomm=nomm.replace("&", "");

                final String finalNomm = nomm;
                recordi = new EnregistrerSon();
                recordi.execute(finalNomm);
                terminé();






            }
        });

        mupload.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.N)
            @Override
            public void onClick(View v) {
                UploadOnServer upload = new UploadOnServer();
                progressbar.setVisibility(View.VISIBLE);
                upload.execute(path,nomfinal);
                progressbar.setVisibility(View.INVISIBLE);

                HttpGetRequest request = new HttpGetRequest();
                request.execute(ip+"/son/creation_son.php?nom_whiz="+nomfinal+"&id_createur="+id);

            }
        });

        mlire.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.N)
            @Override
            public void onClick(View v) {
                LireSonLocal local = new LireSonLocal();
                Uri myUri = Uri.parse("file://"+recordi.getAccess());
                local.execute(myUri);

            }
        });

        return myView;
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    public void terminé(){
        Log.i("Enregistrement","terminé");
        Toast.makeText(getActivity().getApplicationContext(), "Enregistrement terminé", Toast.LENGTH_LONG).show();
        path = recordi.getAccess();
        nomfinal = recordi.getNomSansExtenssions();
        Log.i("nomfinale",nomfinal);
        mlire.setVisibility(View.VISIBLE);
        mupload.setVisibility(View.VISIBLE);
        Log.i("test","");
}

}

还有异步任务:

class EnregistrerSon extends AsyncTask<String,Void,String> {
    private Boolean isRecording = false;
    private Boolean termine = false;
    private String Nom, NOM;



    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    protected String doInBackground(String... params) {
        NOM = params[0];
        if(!isRecording){
            //configuration
            Looper.prepare();
            MediaRecorder mr = new MediaRecorder();
            mr.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
            mr.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
            mr.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
            mr.setAudioChannels(1);
            mr.setAudioEncodingBitRate(1280000);
            mr.setAudioSamplingRate(9500000);
            mr.setOutputFile(getAccess());
            try {mr.prepare();}
            catch (IOException e) {e.printStackTrace();}

            //Demarage du record
            long start_time = System.currentTimeMillis(); //pendant 15 secondes
            long wait_time = 15000;
            long end_time = start_time + wait_time;
            mr.start();
            while (System.currentTimeMillis() < end_time){
                Long temps = end_time - System.currentTimeMillis();

                isRecording = true;
                //pendant 15 secondes
            }
            mr.stop();
            mr.reset();
            mr.release();
            isRecording = false;
            termine = true;
            //fin de l'enregistrement
        }
        return "lol";
    }


    @RequiresApi(api = Build.VERSION_CODES.N)
    protected void onPostExecute(String s) {
        super.onPostExecute(s);


    }

    @TargetApi(Build.VERSION_CODES.N)
    @RequiresApi(api = Build.VERSION_CODES.N)
    String getAccess(){
        MainActivity main = new MainActivity();
        if(Objects.equals(NOM, "Nom") || Objects.equals(NOM, "") || NOM == null ) {
            Calendar now = Calendar.getInstance();
            Nom = now.get(Calendar.HOUR_OF_DAY) + "_" + now.get(Calendar.DAY_OF_MONTH) + "_" + now.get(Calendar.MONTH) + "_" + now.get(Calendar.YEAR);
        }
        else{
            Nom = NOM;
        }
        File directory = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Whizz/");
        directory.mkdirs();
        String filename = directory +"/"+Nom+".mp3";
        Log.i("filename",filename);
        return filename;
    }

    Boolean getTerminé(){
        return termine;
    }

    String getNomSansExtenssions(){
        return Nom;
    }

}

【问题讨论】:

    标签: java android android-fragments android-asynctask android-toast


    【解决方案1】:

    AsyncTask 类中执行你的方法terminé。我建议有以下几点:

    1. EnregistrerSon 类中创建FragmentEnregistrer 的实例字段。

      private FragmentEnregistrer fragmentEnregistrer;
      
    2. EnregistrerSon 类中创建一个构造函数,其预期参数为 FragmentEnregistrer 类,并将参数分配给字段变量。

      public EnregistrerSon(FragmentEnregistrer fe) {
       this.fragmentEnregistrer = fe;
      }
      
    3. 然后可以在onPostExecute方法中调用terminé方法,如下:

      protected void onPostExecute(String s) {
        super.onPostExecute(s);
        this.fragmentEnregistrer.terminé();
      }
      
    4. 最后,在EnregistrerSon 实例化上传递FragmentEnregistrer 对象的实例。

      recordi = new EnregistrerSon(FragmentEnregistrer.this);
      recordi.execute(finalNomm);
      

    【讨论】:

      【解决方案2】:

      首先,while (!recordi.getterminé){} terminé(); 行没有意义,它等于:

      while (!recordi.getterminé){
      
      } 
      terminé();
      

      关于onPostExecute,是的,在里面写函数调用即可:

      protected void onPostExecute(String s) {
      
          // Anything here will be executed at the end, when doInBackground finishes
          terminé();
      }
      

      【讨论】:

      • 这是不可能的:我有这个错误:无法解析方法 terminé() .. 感谢您的帮助
      • 对,那是因为它们属于不同的类。查看answer below 进行修复。
      【解决方案3】:

      使用广播/接收器模式,onhandleintent() 将在 UI 线程上运行,您可以在其中使按钮可见。
      1.启动异步任务。 2.定义一个广播接收器,在你的活动中实例化一个并相应地注册/注销它。 3.在异步任务的onpostexecute()中调用sendBroadcast。实例化 AsyncTask 时可能需要传递上下文参数。 您应用的广播接收器(您在第 2 步中实例化的那个)的 onHandleIntent 方法将在 UI 线程上运行,从而确保所有这些 UI 更新安全。

      【讨论】:

      • 这是我在 stackoverflow 上发布之前尝试使用的,但对我来说它不起作用(应用程序不断崩溃),但感谢您的帮助。
      • 你使用广播接收器了吗?如果有,请在问题中提及。建议您回答对我们很有帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 2021-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多