You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Volley+JSON连接SQL Server到Android Studio遇连接错误及图片显示求助

Hey there! Let's break down and fix your two core issues: the connection error stopping your ListView from loading data, and displaying varbinary(MAX) images from SQL Server in your ListView.


1. Troubleshooting the "Error in connection" Issue

First, let's get your data loading working step by step:

Step 1: Verify Server & URL Reachability

  • Double-check that your URL http://myIP-Here/MSSQL/client.php works directly in your phone's browser. If it doesn't:
    • Replace myIP-Here with your computer's local network IP (e.g., 192.168.1.100) instead of localhost or 127.0.0.1 (your phone can't reach your computer's loopback address).
    • Ensure your computer and phone are on the same WiFi network.
    • Confirm the PHP file path is correct (no typos in /MSSQL/client.php).

Step 2: Add Critical Network Permissions

Make sure your AndroidManifest.xml includes the internet permission (Volley can't send requests without this):

<uses-permission android:name="android.permission.INTERNET" />

For Android 9+, you also need to allow cleartext HTTP (if you're not using HTTPS):

<application
    ...
    android:usesCleartextTraffic="true">
    ...
</application>

Step 3: Fix Adapter Initialization Order

Your current code sets the adapter before adding data to rowItems—so the adapter never sees the new data. Here's the corrected subject() method:

public void subject(){
    String url = "http://your-local-ip/MSSQL/client.php";
    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
        new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                Log.d("Raw Response", response);
                try {
                    JSONObject jsonObj = new JSONObject(response);
                    peoples = jsonObj.getJSONArray("json");
                    mylistview = findViewById(R.id.list);
                    
                    // Clear old data first
                    rowItems.clear();
                    
                    // Populate data into rowItems
                    for(int i=0;i<peoples.length();i++) {
                        JSONObject c = peoples.getJSONObject(i);
                        RowItem goodsItems = new RowItem();
                        goodsItems.setItem_id(c.getInt("item_id"));
                        goodsItems.setItem_name(c.getString("item_name"));
                        rowItems.add(goodsItems);
                    }
                    
                    // Initialize adapter AFTER data is ready
                    adapter = new CustomAdapter(MainActivity.this, rowItems);
                    mylistview.setAdapter(adapter);
                    mylistview.setOnItemClickListener(MainActivity.this);
                    
                } catch (JSONException e) {
                    e.printStackTrace();
                    Toast.makeText(MainActivity.this, "JSON Parse Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
                }
            }
        }, 
        new Response.ErrorListener() {
            public void onErrorResponse(VolleyError error) {
                // Get detailed error info instead of generic message
                String errorMsg = "";
                if (error instanceof NetworkError) {
                    errorMsg = "Check your WiFi/data connection";
                } else if (error instanceof ServerError) {
                    errorMsg = "Server error - check PHP logs";
                    // Print server's error response (if available)
                    if (error.networkResponse != null) {
                        String serverError = new String(error.networkResponse.data);
                        Log.e("Server Error", serverError);
                    }
                } else if (error instanceof TimeoutError) {
                    errorMsg = "Request timed out - server might be slow";
                }
                Toast.makeText(MainActivity.this, errorMsg, Toast.LENGTH_LONG).show();
                Log.e("Volley Error", errorMsg, error);
            }
        }){
    @Override
    protected Map<String, String> getParams() {
        Map<String, String> params = new HashMap<>();
        return params;
    }
};
RequestQueue requestQueue = Volley.newRequestQueue(MainActivity.this);
requestQueue.add(stringRequest);
}

Step 4: Validate PHP JSON Output

Ensure your client.php returns only valid JSON (no extra echo statements or HTML). A valid response should look like:

{"json":[{"item_id":1,"item_name":"Product 1"},{"item_id":2,"item_name":"Product 2"}]}

Use an online JSON validator to check the output.


2. Displaying varbinary(MAX) Images from SQL Server

There are two reliable ways to handle this—pick the one that fits your image size:

Option 1: Base64 String in JSON (For Small Images)

  1. Modify your PHP code to convert varbinary data to a Base64 string:
    // Assuming your image column is named 'item_image'
    $item_image = base64_encode($row['item_image']);
    // Add this to your JSON output array
    
  2. Update your RowItem class to hold the Base64 string:
    public class RowItem {
        public int item_id;
        public String item_name;
        public String item_image_base64; // New field
    
        public RowItem() {}
    
        // Getters and setters
        public int getItem_id() { return item_id; }
        public void setItem_id(int item_id) { this.item_id = item_id; }
        public String getItem_name() { return item_name; }
        public void setItem_name(String item_name) { this.item_name = item_name; }
        public String getItem_image_base64() { return item_image_base64; }
        public void setItem_image_base64(String item_image_base64) { this.item_image_base64 = item_image_base64; }
    }
    
  3. Parse the Base64 field in your onResponse method:
    goodsItems.setItem_image_base64(c.getString("item_image"));
    
  4. Load the image in CustomAdapter:
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (inflater == null)
            inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (convertView == null)
            convertView = inflater.inflate(R.layout.list_item, null);
    
        TextView item_id = convertView.findViewById(R.id.item_id);
        TextView item_name = convertView.findViewById(R.id.item_name);
        ImageView image = convertView.findViewById(R.id.imView);
    
        final RowItem m = rowItems.get(position);
        item_id.setText(String.valueOf(m.getItem_id()));
        item_name.setText(m.getItem_name());
    
        // Load Base64 image
        if (m.getItem_image_base64() != null && !m.getItem_image_base64().isEmpty()) {
            byte[] decodedBytes = Base64.decode(m.getItem_image_base64(), Base64.DEFAULT);
            Bitmap bitmap = BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
            image.setImageBitmap(bitmap);
        } else {
            // Set a default placeholder image
            image.setImageResource(R.drawable.default_image);
        }
    
        return convertView;
    }
    

Option 2: Separate Image Endpoint (For Large Images)

This is better for bigger images since Base64 adds overhead.

  1. Create a PHP endpoint (e.g., get_image.php) to return the image stream:
    <?php
    $item_id = $_GET['item_id'];
    // Connect to SQL Server, query the item_image column for this item_id
    header("Content-Type: image/jpeg"); // Adjust based on your image type (png, etc.)
    echo $row['item_image'];
    ?>
    
  2. Use Picasso (a popular image loading library) to load the image in your adapter:
    • Add Picasso to your app-level build.gradle:
      implementation 'com.squareup.picasso:picasso:2.71828'
      
    • Update your CustomAdapter's getView method:
      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
          // ... existing code ...
          ImageView image = convertView.findViewById(R.id.imView);
          final RowItem m = rowItems.get(position);
      
          // Load image from the endpoint
          Picasso.with(activity)
              .load("http://your-local-ip/MSSQL/get_image.php?item_id=" + m.getItem_id())
              .resize(300, 300)
              .placeholder(R.drawable.loading_image)
              .error(R.drawable.error_image)
              .into(image);
      
          return convertView;
      }
      

内容的提问来源于stack exchange,提问作者Emily

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 09:08:46