Android异步任务导致冻结

Android异步任务导致冻结,android,android-asynctask,Android,Android Asynctask,我使用的是一种API,它可以为我提供德国的加油站。我使用Asynctask获取加油站的位置和名称 我正在将这些数据放入列表视图中。对于listView,我实现了setOnItemClickListener方法,该方法当前位于doInBackground中。如果单击某个项目,将打开一个新布局,其中再次列出所有获取的数据,没有什么特别的 在办公室我使用的是Android Studio 3.2.1(Windows),在家我使用的是Android Studio 2.3.2(Linux Ubuntu 64

我使用的是一种API,它可以为我提供德国的加油站。我使用Asynctask获取加油站的位置和名称

我正在将这些数据放入列表视图中。对于listView,我实现了
setOnItemClickListener
方法,该方法当前位于
doInBackground
中。如果单击某个项目,将打开一个新布局,其中再次列出所有获取的数据,没有什么特别的

在办公室我使用的是Android Studio 3.2.1(Windows),在家我使用的是Android Studio 2.3.2(Linux Ubuntu 64位)

在家里,我收到了一条警告,即
setonimclicklistener
不应位于
DoInBackground
中。我知道,UI操作不应该存在,是的

但在办公室,我没有收到这个警告。代码的语法是正确的,当我从office pc启动它时,一切正常

当我在家里做同样的事情时,我的整个手机(三星Galaxy S7)崩溃(System.UI已停止工作),甚至一次硬复位都不起作用。对于我的家用笔记本电脑,为了使用Java 1.8,API需要启用插孔

当我向下滚动ListView并单击项目时,会出现冻结。下面是代码,我真的不知道这是什么样的错误:

public class ListOfGasStations extends AppCompatActivity {
Button button;
EditText editText;
ListView listView;
List<String> names = new ArrayList<String>();
int size;
String[] locationArray;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.list_of_gas_stations);


    editText = findViewById(R.id.inputaddress);
    button = findViewById(R.id.buttonaddress);
    listView = findViewById(R.id.listviewgas);


    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            new Test().execute();


        }
    });


}

class Test extends AsyncTask<Void, Void, Void> {
    @SuppressLint("NewApi")
    @Override
    protected Void doInBackground(Void... params) {
        double addresslat = getLat(String.valueOf(editText.getText()));
        double addresslong = getLong(String.valueOf(editText.getText()));


        StationListResult result;
                Tankerkoenig.Api api = new Tankerkoenig.ApiBuilder()
                .withApiKey("MY_API_KEY")
                .build();

        try {
            result = api.list(addresslat, addresslong)
                    .setSorting(StationListRequest.SortingRequestType.DISTANCE)
                    .setGasRequestType(GasRequestType.DIESEL)
                    .setSearchRadius(5)
                    .execute();


            size = result.getStations().size();
            int sizeOfStations;


            System.out.println("Size" + size);
            locationArray = new String[size];


            for (int k = 0; k < size; k++) {
                //size of the station names
                sizeOfStations = String.valueOf(result.getStations().get(k).getBrand()).length();
                //get gas stations name
                String removeUmlaute = String.valueOf(result.getStations().get(k).getBrand()).substring(9, sizeOfStations - 1).toUpperCase();



                //get street names
                String location = String.valueOf(result.getStations().get(k).getLocation().getStreetName();

                locationArray[k] = location;



                names.add(removeUmlaute + "\n" + "\n" + location");

                listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                        for (int i = 0; i < size; i++) {
                            if (position == i) {
                                Intent intent = new Intent(ListOfGasStations.this, NavToLocation.class);
                                intent.putExtra("message", locationArray[i]);

                                startActivity(intent);

                            }
                        }
                    }
                });

            }


        } catch (RequesterException e) {
            e.printStackTrace();
        }

        return null;
    }

    @Override
    protected void onPostExecute(Void foo) {
        super.onPostExecute(foo);
        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(ListOfGasStations.this, android.R.layout.simple_list_item_1, names);
        listView.setAdapter(arrayAdapter);


    }


}


public double getLat(String address) {
    double p1 = 0;
    Geocoder coder = new Geocoder(this);
    try {
        ArrayList<Address> addresses = (ArrayList<Address>) coder.getFromLocationName(editText.getText().toString(), 1);
        for (Address add : addresses) {
            p1 = add.getLatitude();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return p1;
}

public double getLong(String address) {
    double p2 = 0;
    Geocoder coder = new Geocoder(this);
    try {
        ArrayList<Address> addresses = (ArrayList<Address>) coder.getFromLocationName(editText.getText().toString(), 1);
        for (Address add : addresses) {
            p2 = add.getLongitude();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return p2;
}

}
公共类ListofAsstations扩展了AppCompatActivity{
按钮;
编辑文本编辑文本;
列表视图列表视图;
列表名称=新的ArrayList();
整数大小;
字符串[]位置数组;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(右侧布局、加油站列表);
editText=findViewById(R.id.inputaddress);
按钮=findViewById(R.id.buttonaddress);
listView=findViewById(R.id.listviewgas);
setOnClickListener(新视图.OnClickListener(){
@凌驾
公共void onClick(视图v){
新测试().execute();
}
});
}
类测试扩展了异步任务{
@SuppressLint(“新API”)
@凌驾
受保护的Void doInBackground(Void…参数){
双地址lat=getLat(String.valueOf(editText.getText());
double addresslong=getLong(String.valueOf(editText.getText());
统计结果;
Tankerkoenig.Api=新的Tankerkoenig.ApiBuilder()
.使用API密钥(“我的API密钥”)
.build();
试一试{
结果=api.list(addresslat,addresslong)
.setSorting(StationListRequest.SortingRequestType.DISTANCE)
.setGasRequestType(GasRequestType.DIESEL)
.setSearchRadius(5)
.execute();
size=result.getStations().size();
国际尺寸统计;
系统输出打印项次(“尺寸”+尺寸);
locationArray=新字符串[大小];
对于(int k=0;k
不同IDE版本上的警告可能不同。冻结UI是有原因的

  • 可能是listview项目太长。导致listview一次加载所有项目。(解决方案:最好使用
    回收视图
  • 确实,您不能从异步线程中触摸UI元素,但可以在
    doInBackground
    中调用
    onclick
    解决方案:
    uiThread
    中使用它)

  • 您正在为每个listViewItem调用onclick,这意味着您在doInBackground中创建了一个内存。重用它可能是个问题。(因此,在
    onPostExecute
    中或在完成
    后创建
    onclik