Интернет-сокет останавливает приложение на Android - PullRequest
0 голосов
/ 23 октября 2018

У меня проблема с моим приложением.У меня есть MainActivity, где находится ящик с фрагментами.Из фрагмента сканирования я называю «Активность сканирования».Эта часть работает.И когда я нажимаю кнопку «Назад», происходит возврат в MainActivity со ScanFragment.И есть также операция сокета, чтобы послать код, и возможно есть проблема.Когда я отключаю Wi-Fi, он показывает ошибку ввода-вывода в Toast, но когда я пытаюсь отправить данные, он переходит в черный экран.Я обнаружил проблему в профилировщике, что MainActivity не запускаются после закрытия сканирования, но приложение все еще работает.

Image of Missing Activity

Через некоторое время андроид спросит, закрыто ли не отвечающее приложение.Я попытался переместить все классы и функции в MainActivity, но потом сканер не запустился.Спасибо за любую помощь

Мой код MainActivity.java:

public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
    private DrawerLayout drawer;

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

        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        drawer = findViewById(R.id.drawer_layout);

        NavigationView navigationView = findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);

        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.addDrawerListener(toggle);
        toggle.syncState();

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ScanFragment()).commit();
            navigationView.setCheckedItem(R.id.nav_scan);
        }
    }

    @Override
    public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
        switch (menuItem.getItemId()) {
            case R.id.nav_scan:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ScanFragment()).commit();
                break;
            case R.id.nav_okruh:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new OkruhFragment()).commit();
                break;
            case R.id.nav_kzavozu:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new KZavozuFragment()).commit();
                break;
            case R.id.nav_zprava:
                getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ZpravaFragment()).commit();
                break;
        }
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }

    @Override
    public void onBackPressed() {
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }
}

Код ScanFragment.java:

public class ScanFragment extends Fragment {
    String kod;
    String hostname = (address);
    int port = (number);

    Date date;
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SS");

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_scan, container, false);
        Button button = (Button) view.findViewById(R.id.button2);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                zapnoutSkener();
            }
        });
        Button rucne = (Button) view.findViewById(R.id.button3);
        final EditText rucneKod = (EditText) view.findViewById(R.id.numberInput);

        rucne.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                odeslat(rucneKod.getText().toString());
            }
        });
        return view;
    }

    public class Spojeni extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... strings) {
            Log.i("hodnota", strings[0]);
            Log.i("kod", strings[1]);
            try (Socket socket = new Socket(hostname, port)) {
                OutputStream outputStream = socket.getOutputStream();
                InputStream inputStream = socket.getInputStream();

                PrintWriter writer = new PrintWriter(outputStream, true);
                writer.println(strings[0] + ";" + kod + ";" + simpleDateFormat.format(date));

                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                String line = reader.readLine();
                socket.close();
                return line;
            } catch (UnknownHostException e) {
                return "Server nebezi, zopakujte odeslani";
            } catch (IOException e) {
                return "I/O Error, zkontrolujte pripojeni k internetu";
            } catch (Exception e) {
                return "Obecny error";
            }
        }
    }

    public void zapnoutSkener() {
        Intent intent = new Intent(getActivity(), ScanOkno.class);
        Toast.makeText(getActivity(), "Zapinani akce", Toast.LENGTH_LONG).show();
        Log.i("Zapinani skeneru", "ted");
        startActivityForResult(intent, 1);
    }

    public void odeslat(String kod) {
        date = Calendar.getInstance().getTime();
        Toast.makeText(getActivity(), "Odesílám kód: " + kod, Toast.LENGTH_SHORT).show();
        Spojeni spojit = new Spojeni();
        String odpoved = null;
        try {
            odpoved = spojit.execute("SCAN", kod).get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.i("Odpoved", odpoved);
        Toast.makeText(getActivity(), "Odpoved: " + odpoved, Toast.LENGTH_LONG).show();
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 1) {
            Log.i("KOD", String.valueOf(resultCode));
            if (resultCode == 1) {
                String result = data.getStringExtra("code");
                Log.i("Vysledek", result);
                odeslat(result);
            }
        }
    }
}

Код активности сканера ScanOkno.java:

public class ScanOkno extends AppCompatActivity implements BarcodeReader.BarcodeReaderListener {

    private BarcodeReader barcodeReader;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scan_okno);
        barcodeReader = (BarcodeReader) getSupportFragmentManager().findFragmentById(R.id.barcode_fragment);
    }

    @Override
    public void onScanned(Barcode barcode) {
        // play beep sound
        barcodeReader.playBeep();
        String kod = barcode.rawValue;
        barcodeReader.pauseScanning();
        Intent intent = new Intent();
        intent.putExtra("code", barcode.rawValue);
        setResult(1, intent);
        finish();
        //Intent intent = new Intent(getApplicationContext(), MainActivity.class);
        //intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
    }

    @Override
    public void onScannedMultiple(List<Barcode> list) {

    }

    @Override
    public void onBitmapScanned(SparseArray<Barcode> sparseArray) {

    }

    @Override
    public void onScanError(String s) {

    }

    @Override
    public void onCameraPermissionDenied() {
        Toast.makeText(getApplicationContext(), "Camera permission denied!", Toast.LENGTH_LONG).show();
    }
}

1 Ответ

0 голосов
/ 23 октября 2018
odpoved = spojit.execute("SCAN", kod).get()

это ваша проблема.Вызов get() в AsyncTask блокирует текущий поток до тех пор, пока задача не будет завершена, что в сущности отрицательно сказывается на назначении AsyncTask.

Рассмотрите возможность использования обратного вызова.

Во-первых, сделайте Spojeni статическим классом:

public static class Spojeni extends AsyncTask<String, Void, String>

Это предотвратит утечки памяти.Я вижу некоторые переменные, к которым вы обращаетесь внутри родительского класса, но вы можете передать их в своем вызове на execute() и извлечь их из вашей AsyncTask.

Затем создайте интерфейс (может быть потомкомScanFragment или в своем собственном файле):

public interface OnTaskCompleteListener {
    void onTaskComplete(String result);
}

Добавить конструктор и глобальную переменную в AsyncTask:

private OnTaskCompleteListener listener;

public Spojeni(OnTaskCompleteListener listener) {
    this.listener = listener;
}

И реализовать onPostExecute():

@Override
public void onPostExecute(String result) {
    listener.onTaskComplete(result);
}

Когда вы создаете экземпляр Spojeni:

new Spojeni(new OnTaskCompleteListener() {
    @Override
    public void onTaskComplete(String result) {
        //handle the result
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...