在 AsyncTask 中使用 getSupportFragmentManager()

Posted

技术标签:

【中文标题】在 AsyncTask 中使用 getSupportFragmentManager()【英文标题】:Using getSupportFragmentManager() inside AsyncTask 【发布时间】:2018-03-01 11:52:19 【问题描述】:

我有一个 Activity,它有一个 Navigation Drawer,它有很多按钮,其中一个指向 fragment。 问题是我必须创建一个AsyncTask 才能从服务器获取一些信息,但我无法在AsyncTask 中使用getSupportFragmentManager()。 我尝试使用上下文或活动,但无法正常工作。 我收到此错误无法解决方法getSupportFragmentManager()

AsyncTask.java:

    import android.app.Activity;
    import android.app.ProgressDialog;
    import android.content.Context;
    import android.content.Intent;
    import android.os.AsyncTask;
    import android.support.v4.app.FragmentManager;
    import android.util.Log;
    import android.view.View;
    import android.widget.ProgressBar;
    import android.widget.Toast;


    public class AsyncTask extends AsyncTask<Void, Void, String> 
        private Context c;
        private String urlAddress;
        private String token;
        private DatabaseHelper db;
        private Activity mainActivity;

        public AsyncTask(Context c, DatabaseHelper databaseHelper, String urlAddress, Activity activity) 
            this.c = c;
            this.db = databaseHelper;
            this.urlAddress = urlAddress;
            this.mainActivity = activity;
            //GET token FROM database
            this.token = db.getValueFromColumn(0, DatabaseHelper.getTableUser(), DatabaseHelper.getUserToken());
        

        @Override
        protected String doInBackground(Void... params) 
            return this.send();
        

        @Override
        protected void onPostExecute(String response) 
            super.onPostExecute(response);
            if (response != null) 
                //SUCCESS
mainActivity.getSupportFragmentManager().beginTransaction()
                    .add(R.id.content_frame
                            , new SessionsFragment())
                    .addToBackStack("back")
                    .commit();
             else 
                //NO SUCCESS

            
        

        private String send() 
            //CONNECT
            HttpURLConnection connection = Connector.connect(urlAddress);
            if (connection == null) 
                return null;
            
            try 
                OutputStream outputStream = connection.getOutputStream();
                //WRITE
                BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
                bufferedWriter.write(new DataPackager(token).packData());
                bufferedWriter.flush();
                //RELEASE RES
                bufferedWriter.close();
                outputStream.close();
                //HAS IT BEEN SUCCESSFUL?
                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) 
                    //GET EXACT RESPONSE
                    InputStream stream = connection.getInputStream();
                    BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
                    StringBuilder buffer = new StringBuilder();
                    String line;
                    //READ LINE BY LINE
                    while ((line = reader.readLine()) != null) 
                        buffer.append(line);
                    
                    String finalJson = buffer.toString();

                    JSONObject parentObject = new JSONObject(finalJson);
                    JSONObject secondParentObject = parentObject.getJSONObject("data");


                    //json getter and adder to database
                    JSONArray array = secondParentObject.getJSONArray("s");
                    for (int i = 0; i < array.length(); i++) 
                        JSONObject finalObject = array.getJSONObject(i);
                        db.SessionsAddJson(finalObject);
                        //RELEASE RES
                        reader.close();
                    

                    return "c";
                 else 

                
             catch (IOException | JSONException e) 
                e.printStackTrace();
             finally 
                connection.disconnect();
            
            return null;
        
    

我通过以下方式调用任务:

new $AsyncTask(getApplicationContext(), db, URL, MyActivity.this).execute();

感谢您的帮助。

【问题讨论】:

你遇到了什么错误,在这里发布 @SunilP 无法解析方法“getsupportfragmentmanager()” 尝试使用getFragmentManager() 你看过这里吗? ***.com/questions/27425547/… @Hetfieldan24 我的片段是 android.support.v4.app.Fragment 所以我不能使用 getFragmentManager() 【参考方案1】:

更新:

你应该在构造函数中传递AppCompatActivity,像这样:

替换 private Activity mainActivity;private AppCompatActivity mainActivity; 当你使用它时:替换 new $AsyncTask(getApplicationContext(), db, URL).execute();new $AsyncTask(getApplicationContext(), db, URL, YourCurrentActivity.this).execute(); 注意YourCurrentActivity 应该是extends AppCompatActivity

您只是将AppCompatActivityActivity 混淆了。 Activity没有getSupportFragmentManager(),但是AppCompatActivity有这个。

【讨论】:

请完整发布您的 AsyncTask 代码。以及使用 AsyncTask 的代码部分。 究竟是什么不起作用?如果你按照我写的那样做,你就不会出现这个错误:“无法解析方法'getsupportfragmentmanager()'”,因为AppCompatActivity有这个。 尝试替换'private Activity mainActivity;'与'私人 AppCompatActivity mainActivity;'当你使用它时:替换 'new $AsyncTask(getApplicationContext(), db, URL).execute();'用'新 $AsyncTask(getApplicationContext(), db, URL, YourCurrentActivity.this).execute();'请注意,YourCurrentActivity 应该扩展 AppCompatActivity。 你只是将 AppCompatActivity 与 Activity 混淆了。 Activity没有getSupportFragmentManager(),但是AppCompatActivity有这个。 成功了,谢谢,请编辑您的答案或发布一个新答案,以便我接受。【参考方案2】:

如果您使用的是 asyntask 类,那么加载您需要上下文的片段,即特定活动的上下文。

因此,将上下文类型转换为要加载片段的相应活动,然后 onPostExecute 使用特定活动片段管理器加载片段。

public class sampleAsyncTask extends AsyncTask<Void, Void, Void> 

private YourActivity mActivity;

@Override
protected Void doInBackground(Void... voids) 
    return null;


public sampleAsyncTask(Context context) 
    super();
    activity = (YourActivity) context;


@Override
protected void onPreExecute() 
    super.onPreExecute();


@Override
protected void onPostExecute(Void aVoid) 
    super.onPostExecute(aVoid);
    mActivity.getSupportFragmentManager().beginTransaction()
            .add(R.id.content_frame
                    , new Fragment())
            .addToBackStack("back")
            .commit();


编辑

在这行代码中,而不是将活动类型转换的通用引用存储到特定活动,即您当前的活动。

private YOURACTIVITY mainActivity;
public AsyncTask(Context c, DatabaseHelper databaseHelper, String urlAddress, Activity activity) 
        this.c = c;
        this.db = databaseHelper;
        this.urlAddress = urlAddress;

        //TypeCast to your particular activity
        mainActivity =(YOURACTIVITY) activity;

        this.token = db.getValueFromColumn(0, DatabaseHelper.getTableUser(), DatabaseHelper.getUserToken());
    

【讨论】:

哦..那么不可能像那个家伙那样添加片段..片段管理器属于特定的活动..就像一个活动有自己的管理器来处理片段 顺便说一句,您可以在 onPostExecute 方法中添加回调并在获取回调时加载片段 检查可以使它成为可能的答案:) 替换私有Activity mainActivity;与私有 AppCompatActivity mainActivity;【参考方案3】:

您的活动应该是AppCompatActivity 而不是Activity

【讨论】:

我的活动扩展了 AppCompatActivity 您的 AsyncTask 是否在此活动中? @Zacktamondo 将你的 AsyncTask 移动到活动中 将您的 Activity 导入更改为 AppCompatActivity @Zacktamondo【参考方案4】:

试试这个

getActivity().getFragmentManager().beginTransaction()
                .add(R.id.content_frame
                        , new Fragment())
                .addToBackStack("back")
                .commit();

【讨论】:

能否请您分享您的片段类的完整代码,以便我们找出问题所在? 兄弟,如果您的异步不在片段中(单类)...那么您必须将您的活动与它一起传递。 尝试 MainActivity.this .....当你调用你的异步任务时 new $AsyncTask(mainactivity.this, db, URL).execute(); 兄弟将您的异步类放入片段中,然后您将获得您的活动。 还有其他办法吗?

以上是关于在 AsyncTask 中使用 getSupportFragmentManager()的主要内容,如果未能解决你的问题,请参考以下文章

在 AsyncTask 中使用 getSupportFragmentManager()

AsyncTask - 如何在AsyncTask中使用带有postDelayed(Runnable,int)的Handler?

在 Asynctask 中使用 Thread.sleep 时出错

如何在 Android 中正确使用 AsyncTask [关闭]

Android中AsyncTask使用具体解释

在 android studio 中使用 AsyncTask 从套接字读取数据