为什么从Service返回时ListView不会更新?

时间:2016-09-04 04:38:56

标签: android android-studio android-fragments android-activity android-service

Choose_Country

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

public class Choose_Country extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_choose__country);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);


        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

}

Choose_CountryFragment

package com.A.B;

import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RadioGroup;

import com.A.B.service.GetNumberService;

/**
 * A placeholder fragment containing a simple view.
 */
public class Choose_CountryFragment extends Fragment {

    private RadioGroup radioGroup;

    public Choose_CountryFragment() {
    }

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

        radioGroup = (RadioGroup) rootView.findViewById(R.id.country_choice_radio);
        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener()
        {
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch(checkedId){
                    case R.id.A:
                        // do operations specific to this selection
                        break;

                    case R.id.B:
                        // do operations specific to this selection
                        Intent explicitGetNumberServiceIntent = new Intent(getActivity(), GetNumberService.class);
                        explicitGetNumberServiceIntent.putExtra("country", "B");
                        getActivity().startService(explicitGetNumberServiceIntent);
                        break;
                    case R.id.C:
                        Intent explicitGetNumberServiceIntentN = new Intent(getActivity(), GetNumberService.class);
                        explicitGetNumberServiceIntentC.putExtra("country", "C");
                        getActivity().startService(explicitGetNumberServiceIntentC);
                        break;
                }
            }
        });
        return rootView;
    }


}

GetNumberService

import android.app.IntentService;
import android.content.Intent;
import android.net.Uri;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;

/**
 * An {@link IntentService} subclass for handling asynchronous task requests in
 * a service on a separate handler thread.
 * helper methods.
 *
 *
 */
public class GetNumberService extends IntentService {
    private ArrayList<String> mobileNumberList = new ArrayList<String>();
    public static final String ABC = "com.A.B.ABC";
    private final String LOG_TAG = GetNumberService.class.getSimpleName();

    public GetNumberService() {
        super("GetNumberService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {

        HttpURLConnection urlConnection = null;
        BufferedReader reader = null;


        String NumbersJSON = null;


        if (intent != null) {
            String chosenCountry = intent.getStringExtra("country");

            try{

                final String BASE_URL = "http://1.1.1.1:8080/WebServices/country/";

                Uri buildUri = Uri.parse(BASE_URL).buildUpon()
                        .appendPath(chosenCountry).build();

                URL url = new URL(buildUri.toString());
                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("GET");
                urlConnection.connect();

                // Read the input stream into a String
                InputStream inputStream = urlConnection.getInputStream();
                StringBuffer buffer = new StringBuffer();
                if (inputStream == null) {
                    // Nothing to do.
                    return;
                }
                reader = new BufferedReader(new InputStreamReader(inputStream));

                String line;
                while ((line = reader.readLine()) != null) {
                    // Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
                    // But it does make debugging a *lot* easier if you print out the completed
                    // buffer for debugging.
                    buffer.append(line + "\n");
                }

                if (buffer.length() == 0) {
                    // Stream was empty.  No point in parsing.
                    return;
                }

                NumbersJSON = buffer.toString();

                JSONArray Numbers_Array = new JSONArray(NumbersJSON);

                for(int i = 0; Numbers_Array.length() != 0 && i < Numbers_Array.length(); i++) {
                    NumberList.add(Numbers_Array.getString(i));
                }

                Intent NumbersIntent = new Intent(ABC);
                NumbersIntent.putStringArrayListExtra("Numbers", NumberList);

                LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);
                localBroadcastManager.sendBroadcast(NumbersIntent);

            } catch (IOException e) {
                Log.e(LOG_TAG, "Error ", e);
                // If the code didn't successfully get the weather data, there's no point in attempting
                // to parse it.
            } catch (JSONException e) {
                Log.e(LOG_TAG, e.getMessage(), e);
                e.printStackTrace();
            } finally {
                if (urlConnection != null) {
                    urlConnection.disconnect();
                }
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (final IOException e) {
                        Log.e(LOG_TAG, "Error closing stream", e);
                    }
                }
            }
        }
        return;
    }


}

ChooseNumber

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

import com.a2ndnumber.a2ndnumber.service.GetNumberService;

import java.util.ArrayList;

public class Choose_number extends AppCompatActivity {

    static ArrayList<String> mNumbersList;

    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver(){

        @Override
        public void onReceive(Context context, Intent intent) {
            if(intent.getAction().equals(GetNumberService.ABC)){
                mNumbersList = intent.getStringArrayListExtra("NumberList");
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_choose_number);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        IntentFilter filter = new IntentFilter();
        filter.addAction(GetNumberService.ABC);
        LocalBroadcastManager bm = LocalBroadcastManager.getInstance(this);
        bm.registerReceiver(mBroadcastReceiver, filter);
    }

}

ChooseNumberFragment

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListView;

/**
 * A placeholder fragment containing a simple view.
 */
public class Choose_numberFragment extends Fragment {


    private ArrayAdapter<String> NumberListAdapter;

    public Choose_numberFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        NumberListAdapter = new ArrayAdapter<String>(getActivity(), R.layout.list_item_numbers, R.id.list_item_textview, Choose_number.NumbersList);
        View rootView = inflater.inflate(R.layout.fragment_number, container, false);

        ListView listView = (ListView) rootView.findViewById(R.id.listview_List);
        listView.setAdapter(mNumberListAdapter);

        return rootView;
    }

}

在ChooseCountry Fragment中,我选择了一个国家/地区。应该发生的是,它应该去服务,获取数据并填充数组列表并将填充的数组列表发送到ChooseNumberFragment / ChooseNumber Activity。

实际发生的是,我能够调试直到GetNumberService的onHandleIntent方法的return语句,我注意到数组List中填充了REST服务的值。但该应用程序不会在CHooseNumberList acitivity或fragment中填充arrayLIst。

我也没有得到任何例外。

请帮忙。感谢。

1 个答案:

答案 0 :(得分:0)

看起来您的Choose_number活动确实通过BroadcastReceiver接收List,但它所做的只是将其分配给它自己的实例变量mNumbersList。您需要通知Fragment列表已更改,以便它可以通知ListView数据已更改。 ListView必须知道它的数据已经改变,因此它可以更新和重绘自己。从片段中调用notifyDataSetChanged()来实现此目的。

您的问题也有点不清楚。它询问无法对片段进行膨胀,但在细节中询问ListView没有变化。如果除了ListView问题之外,您还不知道如何给Fragment充气,您需要调用getSupportFragmentManager()然后创建FragmentTransaction。您可以阅读Fragments Guide以了解如何执行此操作。